%!TEX root = std.tex
\rSec0[support]{Language support library}

\rSec1[support.general]{General}

\pnum
This Clause describes the function signatures that are called
implicitly, and the types of objects generated implicitly, during the execution
of some \Cpp{} programs.
It also describes the headers that declare these function
signatures and define any related types.

\pnum
The following subclauses describe
common type definitions used throughout the library,
characteristics of the predefined types,
functions supporting start and termination of a \Cpp{} program,
support for dynamic memory management,
support for dynamic type identification,
support for contract-violation handling,
support for exception processing, support for initializer lists,
and other runtime support,
as summarized in \tref{support.summary}.

\begin{libsumtab}{Language support library summary}{support.summary}
\ref{support.types}       & Common definitions        &
  \tcode{<cstddef>}, \tcode{<cstdlib>}   \\ \rowsep
\ref{support.limits}      & Implementation properties &
  \tcode{<cfloat>}, \tcode{<climits>}, \tcode{<limits>}, \tcode{<version>}    \\ \rowsep
\ref{support.arith.types} & Arithmetic types          &   \tcode{<cstdint>}, \tcode{<stdfloat>}  \\ \rowsep
\ref{support.start.term}  & Start and termination     &   \tcode{<cstdlib>}   \\ \rowsep
\ref{support.dynamic}     & Dynamic memory management &   \tcode{<new>}       \\ \rowsep
\ref{support.rtti}        & Type identification       &   \tcode{<typeinfo>}, \tcode{<typeindex>}  \\ \rowsep
\ref{support.srcloc}      & Source location           &   \tcode{<source_location>} \\ \rowsep
\ref{support.exception}   & Exception handling        &   \tcode{<exception>} \\ \rowsep
\ref{support.contract}    & Contract-violation handling & \tcode{<contracts>} \\ \rowsep
\ref{support.initlist}    & Initializer lists         & \tcode{<initializer_list>} \\ \rowsep
\ref{cmp}                 & Comparisons               &   \tcode{<compare>}   \\ \rowsep
\ref{support.coroutine}   & Coroutines                &   \tcode{<coroutine>} \\ \rowsep
\ref{support.runtime}     & Other runtime support     &
  \tcode{<csetjmp>}, \tcode{<csignal>}, \tcode{<cstdarg>}, \tcode{<cstdlib>}  \\
\end{libsumtab}

\rSec1[support.types]{Common definitions}

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

\indexlibraryglobal{NULL}%
\indexlibraryglobal{offsetof}%
\indexlibraryglobal{ptrdiff_t}%
\indexlibraryglobal{size_t}%
\indexlibraryglobal{max_align_t}%
\indexlibraryglobal{nullptr_t}%
\indexlibraryglobal{byte}%
\begin{codeblock}
// all freestanding
namespace std {
  using ptrdiff_t = @\seebelow@;
  using size_t = @\seebelow@;
  using max_align_t = @\seebelow@;
  using nullptr_t = decltype(nullptr);

  enum class byte : unsigned char {};

  // \ref{support.types.byteops}, \tcode{byte} type operations
  template<class IntType>
    constexpr byte& operator<<=(byte& b, IntType shift) noexcept;
  template<class IntType>
    constexpr byte operator<<(byte b, IntType shift) noexcept;
  template<class IntType>
    constexpr byte& operator>>=(byte& b, IntType shift) noexcept;
  template<class IntType>
    constexpr byte operator>>(byte b, IntType shift) noexcept;
  constexpr byte& operator|=(byte& l, byte r) noexcept;
  constexpr byte operator|(byte l, byte r) noexcept;
  constexpr byte& operator&=(byte& l, byte r) noexcept;
  constexpr byte operator&(byte l, byte r) noexcept;
  constexpr byte& operator^=(byte& l, byte r) noexcept;
  constexpr byte operator^(byte l, byte r) noexcept;
  constexpr byte operator~(byte b) noexcept;
  template<class IntType>
    constexpr IntType to_integer(byte b) noexcept;
}

#define NULL @\seebelow@
#define offsetof(P, D) @\seebelow@
\end{codeblock}

\pnum
The contents and meaning of the header \libheaderdef{cstddef} are the same as
the C standard library header \libheader{stddef.h},
except that it does not declare the type \keyword{wchar_t},
that it does not define the macro \tcode{unreachable},
that it also declares the type \tcode{byte}
and its associated operations\iref{support.types.byteops},
and as noted in
\ref{support.types.nullptr} and
\ref{support.types.layout}.

\xrefc{7.21}

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

\indexheader{cstdlib}%
\indexlibraryglobal{EXIT_FAILURE}%
\indexlibraryglobal{EXIT_SUCCESS}%
\indexlibraryglobal{MB_CUR_MAX}%
\indexlibraryglobal{NULL}%
\indexlibraryglobal{RAND_MAX}%
\indexlibraryglobal{_Exit}%
\indexlibraryglobal{abort}%
\indexlibraryglobal{abs}%
\indexlibraryglobal{aligned_alloc}%
\indexlibraryglobal{at_quick_exit}%
\indexlibraryglobal{atexit}%
\indexlibraryglobal{atof}%
\indexlibraryglobal{atoi}%
\indexlibraryglobal{atol}%
\indexlibraryglobal{atoll}%
\indexlibraryglobal{bsearch}%
\indexlibraryglobal{calloc}%
\indexlibraryglobal{div}%
\indexlibraryglobal{div_t}%
\indexlibraryglobal{exit}%
\indexlibraryglobal{free}%
\indexlibraryglobal{getenv}%
\indexlibraryglobal{labs}%
\indexlibraryglobal{ldiv}%
\indexlibraryglobal{ldiv_t}%
\indexlibraryglobal{llabs}%
\indexlibraryglobal{lldiv}%
\indexlibraryglobal{lldiv_t}%
\indexlibraryglobal{malloc}%
\indexlibraryglobal{mblen}%
\indexlibraryglobal{mbstowcs}%
\indexlibraryglobal{mbtowc}%
\indexlibraryglobal{qsort}%
\indexlibraryglobal{quick_exit}%
\indexlibraryglobal{rand}%
\indexlibraryglobal{realloc}%
\indexlibraryglobal{size_t}%
\indexlibraryglobal{srand}%
\indexlibraryglobal{strtod}%
\indexlibraryglobal{strtof}%
\indexlibraryglobal{strtol}%
\indexlibraryglobal{strtold}%
\indexlibraryglobal{strtoll}%
\indexlibraryglobal{strtoul}%
\indexlibraryglobal{strtoull}%
\indexlibraryglobal{system}%
\indexlibraryglobal{wcstombs}%
\indexlibraryglobal{wctomb}%
\begin{codeblock}
namespace std {
  using size_t = @\seebelow@;                                             // freestanding
  using div_t = @\seebelow@;                                              // freestanding
  using ldiv_t = @\seebelow@;                                             // freestanding
  using lldiv_t = @\seebelow@;                                            // freestanding
}

#define NULL @\seebelow@                                                  // freestanding
#define EXIT_FAILURE @\seebelow@                                          // freestanding
#define EXIT_SUCCESS @\seebelow@                                          // freestanding
#define RAND_MAX @\seebelow@
#define MB_CUR_MAX @\seebelow@

namespace std {
  // Exposition-only function type aliases
  extern "C" using @\placeholdernc{c-atexit-handler}@ = void();                           // \expos
  extern "C++" using @\placeholdernc{atexit-handler}@ = void();                           // \expos
  extern "C" using @\placeholdernc{c-compare-pred}@ = int(const void*, const void*);      // \expos
  extern "C++" using @\placeholdernc{compare-pred}@ = int(const void*, const void*);      // \expos

  // \ref{support.start.term}, start and termination
  [[noreturn]] void abort() noexcept;                                   // freestanding
  int atexit(@\placeholder{c-atexit-handler}@* func) noexcept;                          // freestanding
  int atexit(@\placeholder{atexit-handler}@* func) noexcept;                            // freestanding
  int at_quick_exit(@\placeholder{c-atexit-handler}@* func) noexcept;                   // freestanding
  int at_quick_exit(@\placeholder{atexit-handler}@* func) noexcept;                     // freestanding
  [[noreturn]] void exit(int status);                                   // freestanding
  [[noreturn]] void _Exit(int status) noexcept;                         // freestanding
  [[noreturn]] void quick_exit(int status) noexcept;                    // freestanding

  char* getenv(const char* name);
  int system(const char* string);

  // \ref{c.malloc}, C library memory allocation
  void* aligned_alloc(size_t alignment, size_t size);
  void* calloc(size_t nmemb, size_t size);
  void free(void* ptr);
  void free_sized(void* ptr, size_t size);
  void free_aligned_sized(void* ptr, size_t alignment, size_t size);
  void* malloc(size_t size);
  void* realloc(void* ptr, size_t size);
  size_t memalignment(const void* p);                                   // freestanding

  double atof(const char* nptr);
  int atoi(const char* nptr);
  long int atol(const char* nptr);
  long long int atoll(const char* nptr);
  double strtod(const char* nptr, char** endptr);
  int strfromd(char* s, size_t n, const char* format, double fp);
  int strfromf(char* s, size_t n, const char* format, float fp);
  int strfroml(char* s, size_t n, const char* format, long double fp);
  float strtof(const char* nptr, char** endptr);
  long double strtold(const char* nptr, char** endptr);
  long int strtol(const char* nptr, char** endptr, int base);
  long long int strtoll(const char* nptr, char** endptr, int base);
  unsigned long int strtoul(const char* nptr, char** endptr, int base);
  unsigned long long int strtoull(const char* nptr, char** endptr, int base);

  // \ref{c.mb.wcs}, multibyte / wide string and character conversion functions
  int mblen(const char* s, size_t n);
  int mbtowc(wchar_t* pwc, const char* s, size_t n);
  int wctomb(char* s, wchar_t wchar);
  size_t mbstowcs(wchar_t* pwcs, const char* s, size_t n);
  size_t wcstombs(char* s, const wchar_t* pwcs, size_t n);

  // \ref{alg.c.library}, C standard library algorithms
  void* bsearch(const void* key, void* base, size_t nmemb, size_t size,         // freestanding
                @\placeholder{c-compare-pred}@*@\itcorr[-1]@ compar);
  void* bsearch(const void* key, void* base, size_t nmemb, size_t size,         // freestanding
                @\placeholder{compare-pred}@*@\itcorr[-1]@ compar);
  const void* bsearch(const void* key, const void* base, size_t nmemb,          // freestanding
                      size_t size, @\placeholder{c-compare-pred}@*@\itcorr[-1]@ compar);
  const void* bsearch(const void* key, const void* base, size_t nmemb,          // freestanding
                      size_t size, @\placeholder{compare-pred}@*@\itcorr[-1]@ compar);
  void qsort(void* base, size_t nmemb, size_t size, @\placeholder{c-compare-pred}@*@\itcorr[-1]@ compar);    // freestanding
  void qsort(void* base, size_t nmemb, size_t size, @\placeholder{compare-pred}@*@\itcorr[-1]@ compar);      // freestanding

  // \ref{c.math.rand}, low-quality random number generation
  int rand();
  void srand(unsigned int seed);

  // \ref{c.math.abs}, absolute values
  constexpr int abs(int j);                                             // freestanding
  constexpr long int abs(long int j);                                   // freestanding
  constexpr long long int abs(long long int j);                         // freestanding
  constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ j);            // freestanding-deleted

  constexpr long int labs(long int j);                                  // freestanding
  constexpr long long int llabs(long long int j);                       // freestanding

  constexpr div_t div(int numer, int denom);                            // freestanding
  constexpr ldiv_t div(long int numer, long int denom);                 // freestanding; see \ref{library.c}
  constexpr lldiv_t div(long long int numer, long long int denom);      // freestanding; see \ref{library.c}
  constexpr ldiv_t ldiv(long int numer, long int denom);                // freestanding
  constexpr lldiv_t lldiv(long long int numer, long long int denom);    // freestanding
}
\end{codeblock}

\pnum
The contents and meaning of the header \libheader{cstdlib} are the same as
the C standard library header \libheader{stdlib.h},
except that it does not declare the types \keyword{wchar_t} or \tcode{once_flag},
and does not declare the function \tcode{call_once},
and except as noted in
\ref{support.types.nullptr},
\ref{support.types.layout},
\ref{support.start.term},
\ref{c.malloc},
\ref{c.mb.wcs},
\ref{alg.c.library},
\ref{c.math.rand}, and
\ref{c.math.abs}.
\begin{note}
Several functions have additional overloads in this document,
but they have the same behavior as in the C standard library\iref{library.c}.
\end{note}

\xrefc{7.24}

\rSec2[support.types.nullptr]{Null pointers}

\pnum
\indexlibraryglobal{nullptr_t}%
The type \tcode{nullptr_t} is a synonym
for the type of a \keyword{nullptr} expression, and it
has the characteristics
described in~\ref{basic.fundamental} and~\ref{conv.ptr}.
\begin{note}
Although \keyword{nullptr}'s address cannot be taken, the address of another
\tcode{nullptr_t} object that is an lvalue can be taken.
\end{note}

\pnum
The macro
\indexlibraryglobal{NULL}%
\tcode{NULL}
is an \impldef{definition of \tcode{NULL}} null pointer constant.
\begin{footnote}
Possible definitions include
\tcode{0}
and
\tcode{0L},
but not
\tcode{(void*)0}.
\end{footnote}

\xrefc{7.21}

\rSec2[support.types.layout]{Sizes, alignments, and offsets}

\pnum
The macro
\indexlibraryglobal{offsetof}%
\tcode{offsetof(\placeholder{type}, \placeholder{member-designator})}
has the same semantics as the corresponding macro in
the C standard library header \libheader{stddef.h}, but
accepts a restricted set of \tcode{\placeholder{type}}
arguments in this document.
Use of the \tcode{offsetof} macro with a \tcode{\placeholder{type}}
other than a standard-layout class\iref{class.prop}
is conditionally-supported.
\begin{footnote}
Note that \tcode{offsetof}
is required to work as specified even if unary
\tcode{operator\&}
is overloaded for any of the types involved.
\end{footnote}
The expression \tcode{offsetof(\placeholder{type}, \placeholder{member-designator})}
is never type-dependent\iref{temp.dep.expr} and it is
value-dependent\iref{temp.dep.constexpr} if and only if \tcode{\placeholder{type}} is
dependent. The result of applying the \tcode{offsetof} macro to
a static data member or a function member is undefined.
No operation invoked by the \tcode{offsetof} macro shall throw an exception and
\tcode{noexcept(offsetof(\placeholder{type}, \placeholder{member-designator}))} shall be \tcode{true}.

\pnum
The type \tcode{ptrdiff_t} is an
\impldef{type of \tcode{ptrdiff_t}}
signed integer type that can
hold the difference of two subscripts in an array object, as described in~\ref{expr.add}.

\pnum
The type \tcode{size_t} is an
\impldef{type of \tcode{size_t}}
unsigned integer type that is large enough
to contain the size in bytes of any object\iref{expr.sizeof}.

\pnum
\recommended
An implementation should choose types for \tcode{ptrdiff_t} and \tcode{size_t}
whose integer conversion ranks\iref{conv.rank} are no greater than that of
\tcode{signed long int} unless a larger size is necessary to contain all the possible values.

\pnum
The type
\indexlibraryglobal{max_align_t}%
\tcode{max_align_t} is a trivially copyable standard-layout type whose alignment requirement
is at least as great as that of every scalar type, and whose alignment
requirement is supported in every context\iref{basic.align}.
\tcode{std::is_trivially_default_constructible_v<max_align_t>} is \tcode{true}.

\xrefc{7.21}

\rSec2[support.types.byteops]{\tcode{byte} type operations}

\indexlibrarymember{operator<<=}{byte}%
\begin{itemdecl}
template<class IntType>
  constexpr byte& operator<<=(byte& b, IntType shift) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_integral_v<IntType>} is \tcode{true}.

\pnum
\effects
Equivalent to:
\tcode{return b = b << shift;}
\end{itemdescr}

\indexlibrarymember{operator<<}{byte}%
\begin{itemdecl}
template<class IntType>
  constexpr byte operator<<(byte b, IntType shift) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_integral_v<IntType>} is \tcode{true}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
return static_cast<byte>(static_cast<unsigned int>(b) << shift);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator>>=}{byte}%
\begin{itemdecl}
template<class IntType>
  constexpr byte& operator>>=(byte& b, IntType shift) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_integral_v<IntType>} is \tcode{true}.

\pnum
\effects
Equivalent to:
\tcode{return b = b >> shift;}
\end{itemdescr}

\indexlibrarymember{operator>>}{byte}%
\begin{itemdecl}
template<class IntType>
  constexpr byte operator>>(byte b, IntType shift) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_integral_v<IntType>} is \tcode{true}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
return static_cast<byte>(static_cast<unsigned int>(b) >> shift);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator"|=}{byte}%
\begin{itemdecl}
constexpr byte& operator|=(byte& l, byte r) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return l = l | r;}
\end{itemdescr}

\indexlibrarymember{operator"|}{byte}%
\begin{itemdecl}
constexpr byte operator|(byte l, byte r) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return static_cast<byte>(static_cast<unsigned int>(l) | static_cast<unsigned int>(r));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator\&=}{byte}%
\begin{itemdecl}
constexpr byte& operator&=(byte& l, byte r) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return l = l \& r;}
\end{itemdescr}

\indexlibrarymember{operator\&}{byte}%
\begin{itemdecl}
constexpr byte operator&(byte l, byte r) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return static_cast<byte>(static_cast<unsigned int>(l) & static_cast<unsigned int>(r));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator\caret=}{byte}%
\begin{itemdecl}
constexpr byte& operator^=(byte& l, byte r) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return l = l \caret{} r;}
\end{itemdescr}

\indexlibrarymember{operator\caret}{byte}%
\begin{itemdecl}
constexpr byte operator^(byte l, byte r) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return static_cast<byte>(static_cast<unsigned int>(l) ^ static_cast<unsigned int>(r));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator\~{}}{byte}%
\begin{itemdecl}
constexpr byte operator~(byte b) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return static_cast<byte>(~static_cast<unsigned int>(b));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{to_integer}{byte}%
\begin{itemdecl}
template<class IntType>
  constexpr IntType to_integer(byte b) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_integral_v<IntType>} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return static_cast<IntType>(b);}
\end{itemdescr}

\rSec1[support.limits]{Implementation properties}

\rSec2[support.limits.general]{General}

\pnum
The headers
\libheaderref{limits},
\libheaderref{climits}, and
\libheaderref{cfloat}
supply characteristics of
\indextext{implementation-dependent}%
imple\-mentation-dependent
arithmetic types\iref{basic.fundamental}.

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

\pnum
The header \libheaderdef{version}
supplies implementation-dependent information
about the \Cpp{} standard library
(e.g., version number and release date).

\pnum
\indextext{macro!feature-test}%
Each of the macros defined in \libheader{version} is also defined
after inclusion of any member of the set of library headers
indicated in the corresponding comment in this synopsis.
\begin{note}
Future revisions of this document might replace
the values of these macros with greater values.
\end{note}

\begin{codeblock}
#define @\defnlibxname{cpp_lib_adaptor_iterator_pair_constructor}@ 202106L // also in \libheader{stack}, \libheader{queue}
#define @\defnlibxname{cpp_lib_addressof_constexpr}@               201603L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_algorithm_default_value_type}@      202403L
  // also in \libheader{algorithm}, \libheader{ranges}, \libheader{string}, \libheader{deque}, \libheader{list}, \libheader{forward_list}, \libheader{vector}
#define @\defnlibxname{cpp_lib_algorithm_iterator_requirements}@   202207L
  // also in \libheader{algorithm}, \libheader{numeric}, \libheader{memory}
#define @\defnlibxname{cpp_lib_aligned_accessor}@                  202411L // freestanding, also in \libheader{mdspan}
#define @\defnlibxname{cpp_lib_allocate_at_least}@                 202302L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_allocator_traits_is_always_equal}@  201411L
  // freestanding, also in \libheader{memory}, \libheader{scoped_allocator}, \libheader{string}, \libheader{deque}, \libheader{forward_list}, \libheader{list},
  // \libheader{vector}, \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_any}@                               201606L // also in \libheader{any}
#define @\defnlibxname{cpp_lib_apply}@                             202506L
  // freestanding, also in \libheader{tuple}, \libheader{type_traits}
#define @\defnlibxname{cpp_lib_array_constexpr}@                   201811L
  // freestanding, also in \libheader{iterator}, \libheader{array}
#define @\defnlibxname{cpp_lib_as_const}@                          201510L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_associative_heterogeneous_erasure}@ 202110L
  // also in \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_associative_heterogeneous_insertion}@ 202306L
  // also in \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_assume_aligned}@                    201811L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_atomic_flag_test}@                  201907L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_float}@                      201711L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_is_always_lock_free}@        201603L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_lock_free_type_aliases}@     201907L // also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_min_max}@                    202506L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_reductions}@                 202506L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_ref}@                        202411L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_atomic_shared_ptr}@                 201711L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_atomic_value_initialization}@       201911L // freestanding, also in \libheader{atomic}, \libheader{memory}
#define @\defnlibxname{cpp_lib_atomic_wait}@                       201907L // freestanding, also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_barrier}@                           202302L // also in \libheader{barrier}
#define @\defnlibxname{cpp_lib_bind_back}@                         202306L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_bind_front}@                        202306L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_bit_cast}@                          201806L // freestanding, also in \libheader{bit}
#define @\defnlibxname{cpp_lib_bitops}@                            201907L // freestanding, also in \libheader{bit}
#define @\defnlibxname{cpp_lib_bitset}@                            202306L // also in \libheader{bitset}
#define @\defnlibxname{cpp_lib_bool_constant}@                     201505L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_bounded_array_traits}@              201902L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_boyer_moore_searcher}@              201603L // also in \libheader{functional}
#define @\defnlibxname{cpp_lib_byte}@                              201603L // freestanding, also in \libheader{cstddef}
#define @\defnlibxname{cpp_lib_byteswap}@                          202110L // freestanding, also in \libheader{bit}
#define @\defnlibxname{cpp_lib_char8_t}@                           201907L
  // freestanding, also in \libheader{atomic}, \libheader{filesystem}, \libheader{iosfwd}, \libheader{istream}, \libheader{limits}, \libheader{locale}, \libheader{ostream},
  // \libheader{string}, \libheader{string_view}
#define @\defnlibxname{cpp_lib_chrono}@                            202306L // also in \libheader{chrono}
#define @\defnlibxname{cpp_lib_chrono_udls}@                       201304L // also in \libheader{chrono}
#define @\defnlibxname{cpp_lib_clamp}@                             201603L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_common_reference}@                  202302L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_common_reference_wrapper}@          202302L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_complex_udls}@                      201309L // also in \libheader{complex}
#define @\defnlibxname{cpp_lib_concepts}@                          202207L
  // freestanding, also in \libheader{concepts}, \libheader{compare}
#define @\defnlibxname{cpp_lib_constant_wrapper}@                  202506L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_constexpr_algorithms}@              202306L // also in \libheader{algorithm}, \libheader{utility}
#define @\defnlibxname{cpp_lib_constexpr_atomic}@                  202411L // also in \libheader{atomic}
#define @\defnlibxname{cpp_lib_constexpr_bitset}@                  202207L // also in \libheader{bitset}
#define @\defnlibxname{cpp_lib_constexpr_charconv}@                202207L // freestanding, also in \libheader{charconv}
#define @\defnlibxname{cpp_lib_constexpr_cmath}@                   202306L // also in \libheader{cmath}, \libheader{cstdlib}
#define @\defnlibxname{cpp_lib_constexpr_complex}@                 202306L // also in \libheader{complex}
#define @\defnlibxname{cpp_lib_constexpr_deque}@                   202502L // also in \libheader{deque}
#define @\defnlibxname{cpp_lib_constexpr_dynamic_alloc}@           201907L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_constexpr_exceptions}@              202502L
  // also in \libheader{exception}, \libheader{stdexcept}, \libheader{expected}, \libheader{optional}, \libheader{variant}, and \libheader{format}
#define @\defnlibxname{cpp_lib_constexpr_flat_map}@                202502L // also in \libheader{flat_map}
#define @\defnlibxname{cpp_lib_constexpr_flat_set}@                202502L // also in \libheader{flat_set}
#define @\defnlibxname{cpp_lib_constexpr_format}@                  202511L // also in \libheader{format}
#define @\defnlibxname{cpp_lib_constexpr_forward_list}@            202502L // also in \libheader{forward_list}
#define @\defnlibxname{cpp_lib_constexpr_functional}@              201907L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_constexpr_inplace_vector}@          202502L // also in \libheader{inplace_vector}
#define @\defnlibxname{cpp_lib_constexpr_iterator}@                201811L // freestanding, also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_constexpr_list}@                    202502L // also in \libheader{list}
#define @\defnlibxname{cpp_lib_constexpr_map}@                     202502L // also in \libheader{map}
#define @\defnlibxname{cpp_lib_constexpr_memory}@                  202506L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_constexpr_new}@                     202406L // freestanding, also in \libheader{new}
#define @\defnlibxname{cpp_lib_constexpr_numeric}@                 201911L // freestanding, also in \libheader{numeric}
#define @\defnlibxname{cpp_lib_constexpr_queue}@                   202502L // also in \libheader{queue}
#define @\defnlibxname{cpp_lib_constexpr_set}@                     202502L // also in \libheader{set}
#define @\defnlibxname{cpp_lib_constexpr_stack}@                   202502L // also in \libheader{stack}
#define @\defnlibxname{cpp_lib_constexpr_string}@                  201907L // also in \libheader{string}
#define @\defnlibxname{cpp_lib_constexpr_string_view}@             201811L // also in \libheader{string_view}
#define @\defnlibxname{cpp_lib_constexpr_tuple}@                   201811L // freestanding, also in \libheader{tuple}
#define @\defnlibxname{cpp_lib_constexpr_typeinfo}@                202106L // freestanding, also in \libheader{typeinfo}
#define @\defnlibxname{cpp_lib_constexpr_unordered_map}@           202502L // also in \libheader{unordered_map}
#define @\defnlibxname{cpp_lib_constexpr_unordered_set}@           202502L // also in \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_constexpr_utility}@                 201811L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_constexpr_vector}@                  201907L // also in \libheader{vector}
#define @\defnlibxname{cpp_lib_constrained_equality}@              202411L // freestanding,
  // also in \libheader{utility}, \libheader{tuple}, \libheader{optional}, \libheader{variant}, \libheader{expected}
#define @\defnlibxname{cpp_lib_containers_ranges}@                 202202L
  // also in \libheader{vector}, \libheader{list}, \libheader{forward_list}, \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set},
  // \libheader{deque}, \libheader{queue}, \libheader{stack}, \libheader{string}
#define @\defnlibxname{cpp_lib_contracts}@                         202502L // freestanding, also in \libheader{contracts}
#define @\defnlibxname{cpp_lib_copyable_function}@                 202306L // also in \libheader{functional}
#define @\defnlibxname{cpp_lib_coroutine}@                         201902L // freestanding, also in \libheader{coroutine}
#define @\defnlibxname{cpp_lib_counting_scope}@                    202506L // also in \libheader{execution}
#define @\defnlibxname{cpp_lib_debugging}@                         202403L // freestanding, also in \libheader{debugging}
#define @\defnlibxname{cpp_lib_define_static}@                     202506L // freestanding, also in \libheader{meta}
#define @\defnlibxname{cpp_lib_destroying_delete}@                 201806L // freestanding, also in \libheader{new}
#define @\defnlibxname{cpp_lib_enable_shared_from_this}@           201603L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_endian}@                            201907L // freestanding, also in \libheader{bit}
#define @\defnlibxname{cpp_lib_erase_if}@                          202002L
  // also in \libheader{string}, \libheader{deque}, \libheader{forward_list}, \libheader{list}, \libheader{vector}, \libheader{map}, \libheader{set}, \libheader{unordered_map},
  // \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_exception_ptr_cast}@                202506L // also in \libheader{exception}
#define @\defnlibxname{cpp_lib_exchange_function}@                 201304L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_execution}@                         201902L // also in \libheader{execution}
#define @\defnlibxname{cpp_lib_expected}@                          202211L // also in \libheader{expected}
#define @\defnlibxname{cpp_lib_filesystem}@                        201703L // also in \libheader{filesystem}
#define @\defnlibxname{cpp_lib_flat_map}@                          202511L // also in \libheader{flat_map}
#define @\defnlibxname{cpp_lib_flat_set}@                          202511L // also in \libheader{flat_set}
#define @\defnlibxname{cpp_lib_format}@                            202311L // also in \libheader{format}
#define @\defnlibxname{cpp_lib_format_path}@                       202506L // also in \libheader{filesystem}
#define @\defnlibxname{cpp_lib_format_ranges}@                     202207L // also in \libheader{format}
#define @\defnlibxname{cpp_lib_format_uchar}@                      202311L // also in \libheader{format}
#define @\defnlibxname{cpp_lib_formatters}@                        202302L // also in \libheader{stacktrace}, \libheader{thread}
#define @\defnlibxname{cpp_lib_forward_like}@                      202207L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_freestanding_algorithm}@            202502L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_freestanding_array}@                202311L // freestanding, also in \libheader{array}
#define @\defnlibxname{cpp_lib_freestanding_char_traits}@          202306L // freestanding, also in \libheader{string}
#define @\defnlibxname{cpp_lib_freestanding_charconv}@             202306L // freestanding, also in \libheader{charconv}
#define @\defnlibxname{cpp_lib_freestanding_cstdlib}@              202306L // freestanding, also in \libheader{cstdlib}, \libheader{cmath}
#define @\defnlibxname{cpp_lib_freestanding_cstring}@              202311L // freestanding, also in \libheader{cstring}
#define @\defnlibxname{cpp_lib_freestanding_cwchar}@               202306L // freestanding, also in \libheader{cwchar}
#define @\defnlibxname{cpp_lib_freestanding_errc}@                 202306L
  // freestanding, also in \libheader{cerrno}, \libheader{system_error}
#define @\defnlibxname{cpp_lib_freestanding_execution}@            202502L // freestanding, also in \libheader{execution}
#define @\defnlibxname{cpp_lib_freestanding_expected}@             202311L // freestanding, also in \libheader{expected}
#define @\defnlibxname{cpp_lib_freestanding_feature_test_macros}@  202306L // freestanding
#define @\defnlibxname{cpp_lib_freestanding_functional}@           202306L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_freestanding_iterator}@             202306L // freestanding, also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_freestanding_mdspan}@               202311L // freestanding, also in \libheader{mdspan}
#define @\defnlibxname{cpp_lib_freestanding_memory}@               202502L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_freestanding_numeric}@              202502L // freestanding, also in \libheader{numeric}
#define @\defnlibxname{cpp_lib_freestanding_operator_new}@         @\seebelow@ // freestanding, also in \libheader{new}
#define @\defnlibxname{cpp_lib_freestanding_optional}@             202506L // freestanding, also in \libheader{optional}
#define @\defnlibxname{cpp_lib_freestanding_random}@               202502L // freestanding, also in \libheader{random}
#define @\defnlibxname{cpp_lib_freestanding_ranges}@               202306L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_freestanding_ratio}@                202306L // freestanding, also in \libheader{ratio}
#define @\defnlibxname{cpp_lib_freestanding_string_view}@          202311L // freestanding, also in \libheader{string_view}
#define @\defnlibxname{cpp_lib_freestanding_tuple}@                202306L // freestanding, also in \libheader{tuple}
#define @\defnlibxname{cpp_lib_freestanding_utility}@              202306L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_freestanding_variant}@              202311L // freestanding, also in \libheader{variant}
#define @\defnlibxname{cpp_lib_fstream_native_handle}@             202306L // also in \libheader{fstream}
#define @\defnlibxname{cpp_lib_function_ref}@                      202511L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_gcd_lcm}@                           201606L // freestanding, also in \libheader{numeric}
#define @\defnlibxname{cpp_lib_generator}@                         202207L // also in \libheader{generator}
#define @\defnlibxname{cpp_lib_generic_associative_lookup}@        201304L // also in \libheader{map}, \libheader{set}
#define @\defnlibxname{cpp_lib_generic_unordered_lookup}@          201811L
  // also in \libheader{unordered_map}, \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_hardware_interference_size}@        201703L // freestanding, also in \libheader{new}
#define @\defnlibxname{cpp_lib_has_unique_object_representations}@ 201606L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_hazard_pointer}@                    202306L // also in \libheader{hazard_pointer}
#define @\defnlibxname{cpp_lib_hive}@                              202502L // also in \libheader{hive}
#define @\defnlibxname{cpp_lib_hypot}@                             201603L // also in \libheader{cmath}
#define @\defnlibxname{cpp_lib_incomplete_container_elements}@     201505L
  // also in \libheader{forward_list}, \libheader{list}, \libheader{vector}
#define @\defnlibxname{cpp_lib_indirect}@                          202502L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_initializer_list}@                  202511L
  // freestanding, also in \libheader{initializer_list}
#define @\defnlibxname{cpp_lib_inplace_vector}@                    202406L // also in \libheader{inplace_vector}
#define @\defnlibxname{cpp_lib_int_pow2}@                          202002L // freestanding, also in \libheader{bit}
#define @\defnlibxname{cpp_lib_integer_comparison_functions}@      202002L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_integer_sequence}@                  202511L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_integral_constant_callable}@        201304L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_interpolate}@                       201902L // also in \libheader{cmath}, \libheader{numeric}
#define @\defnlibxname{cpp_lib_invoke}@                            201411L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_invoke_r}@                          202106L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_ios_noreplace}@                     202207L // also in \libheader{ios}
#define @\defnlibxname{cpp_lib_is_aggregate}@                      201703L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_constant_evaluated}@             201811L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_final}@                          201402L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_implicit_lifetime}@              202302L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_invocable}@                      201703L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_layout_compatible}@              201907L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_nothrow_convertible}@            201806L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_null_pointer}@                   201309L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_pointer_interconvertible}@       201907L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_scoped_enum}@                    202011L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_sufficiently_aligned}@           202411L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_is_swappable}@                      201603L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_virtual_base_of}@                202406L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_is_within_lifetime}@                202306L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_jthread}@                           201911L // also in \libheader{stop_token}, \libheader{thread}
#define @\defnlibxname{cpp_lib_latch}@                             201907L // also in \libheader{latch}
#define @\defnlibxname{cpp_lib_launder}@                           201606L // freestanding, also in \libheader{new}
#define @\defnlibxname{cpp_lib_linalg}@                            202511L // also in \libheader{linalg}
#define @\defnlibxname{cpp_lib_list_remove_return_type}@           201806L // also in \libheader{forward_list}, \libheader{list}
#define @\defnlibxname{cpp_lib_logical_traits}@                    201510L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_make_from_tuple}@                   201606L // freestanding, also in \libheader{tuple}
#define @\defnlibxname{cpp_lib_make_reverse_iterator}@             201402L // freestanding, also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_make_unique}@                       201304L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_map_try_emplace}@                   201411L // also in \libheader{map}
#define @\defnlibxname{cpp_lib_math_constants}@                    201907L // also in \libheader{numbers}
#define @\defnlibxname{cpp_lib_math_special_functions}@            201603L // also in \libheader{cmath}
#define @\defnlibxname{cpp_lib_mdspan}@                            202406L // freestanding, also in \libheader{mdspan}
#define @\defnlibxname{cpp_lib_memory_resource}@                   201603L // also in \libheader{memory_resource}
#define @\defnlibxname{cpp_lib_modules}@                           202207L // freestanding
#define @\defnlibxname{cpp_lib_move_iterator_concept}@             202207L // freestanding, also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_move_only_function}@                202110L // also in \libheader{functional}
#define @\defnlibxname{cpp_lib_node_extract}@                      201606L
  // also in \libheader{map}, \libheader{set}, \libheader{unordered_map}, \libheader{unordered_set}
#define @\defnlibxname{cpp_lib_nonmember_container_access}@        201411L
  // freestanding, also in \libheader{array}, \libheader{deque}, \libheader{forward_list}, \libheader{iterator}, \libheader{list}, \libheader{map}, \libheader{regex}, \libheader{set},
  // \libheader{string}, \libheader{unordered_map}, \libheader{unordered_set}, \libheader{vector}
#define @\defnlibxname{cpp_lib_not_fn}@                            202306L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_null_iterators}@                    201304L // freestanding, also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_observable_checkpoint}@             202506L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_optional}@                          202506L // also in \libheader{optional}
#define @\defnlibxname{cpp_lib_optional_range_support}@            202406L // freestanding, also in \libheader{optional}
#define @\defnlibxname{cpp_lib_out_ptr}@                           202311L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_parallel_algorithm}@                202506L
  // also in \libheader{algorithm}, \libheader{numeric}, \libheader{memory}
#define @\defnlibxname{cpp_lib_parallel_scheduler}@                202506L // also in \libheader{execution}
#define @\defnlibxname{cpp_lib_philox_engine}@                     202406L // also in \libheader{random}
#define @\defnlibxname{cpp_lib_polymorphic}@                       202502L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_polymorphic_allocator}@             201902L // also in \libheader{memory_resource}
#define @\defnlibxname{cpp_lib_print}@                             202406L // also in \libheader{print}, \libheader{ostream}
#define @\defnlibxname{cpp_lib_quoted_string_io}@                  201304L // also in \libheader{iomanip}
#define @\defnlibxname{cpp_lib_ranges}@                            202406L
  // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_as_const}@                   202311L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_as_rvalue}@                  202207L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_cache_latest}@               202411L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_cartesian_product}@          202207L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_chunk}@                      202202L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_chunk_by}@                   202202L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_concat}@                     202403L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_contains}@                   202207L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_ranges_enumerate}@                  202302L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_find_last}@                  202207L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_ranges_fold}@                       202207L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_ranges_generate_random}@            202403L // also in \libheader{random}
#define @\defnlibxname{cpp_lib_ranges_indices}@                    202506L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_iota}@                       202202L // freestanding, also in \libheader{numeric}
#define @\defnlibxname{cpp_lib_ranges_join_with}@                  202202L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_repeat}@                     202207L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_reserve_hint}@               202502L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_slide}@                      202202L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@           202106L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_ranges_stride}@                     202207L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_to_container}@               202202L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_to_input}@                   202502L // freestanding, also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_zip}@                        202110L
  // freestanding, also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}
#define @\defnlibxname{cpp_lib_ratio}@                             202306L // freestanding, also in \libheader{ratio}
#define @\defnlibxname{cpp_lib_raw_memory_algorithms}@             202411L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_rcu}@                               202306L // also in \libheader{rcu}
#define @\defnlibxname{cpp_lib_reference_from_temporary}@          202202L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_reference_wrapper}@                 202403L // freestanding, also in \libheader{functional}
#define @\defnlibxname{cpp_lib_reflection}@                        202506L // also in \libheader{meta}
#define @\defnlibxname{cpp_lib_remove_cvref}@                      201711L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_result_of_sfinae}@                  201210L
  // freestanding, also in \libheader{functional}, \libheader{type_traits}
#define @\defnlibxname{cpp_lib_robust_nonmodifying_seq_ops}@       201304L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_sample}@                            201603L // freestanding, also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_saturation_arithmetic}@             202311L // freestanding, also in \libheader{numeric}
#define @\defnlibxname{cpp_lib_scoped_lock}@                       201703L // also in \libheader{mutex}
#define @\defnlibxname{cpp_lib_semaphore}@                         201907L // also in \libheader{semaphore}
#define @\defnlibxname{cpp_lib_senders}@                           202506L // also in \libheader{execution}
#define @\defnlibxname{cpp_lib_shared_mutex}@                      201505L // also in \libheader{shared_mutex}
#define @\defnlibxname{cpp_lib_shared_ptr_arrays}@                 201707L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@              201606L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@                201402L // also in \libheader{shared_mutex}
#define @\defnlibxname{cpp_lib_shift}@                             202202L // also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_simd}@                              202511L // also in \libheader{simd}
#define @\defnlibxname{cpp_lib_simd_complex}@                      202502L // also in \libheader{simd}
#define @\defnlibxname{cpp_lib_simd_permutations}@                 202506L // also in \libheader{simd}
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@           202002L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_smart_ptr_owner_equality}@          202306L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_source_location}@                   201907L // freestanding, also in \libheader{source_location}
#define @\defnlibxname{cpp_lib_span}@                              202311L // freestanding, also in \libheader{span}
#define @\defnlibxname{cpp_lib_span_initializer_list}@             202311L // freestanding, also in \libheader{span}
#define @\defnlibxname{cpp_lib_spanstream}@                        202106L // also in \libheader{iosfwd}, \libheader{spanstream}
#define @\defnlibxname{cpp_lib_ssize}@                             201902L // freestanding, also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_sstream_from_string_view}@          202306L // also in \libheader{sstream}
#define @\defnlibxname{cpp_lib_stacktrace}@                        202011L // also in \libheader{stacktrace}
#define @\defnlibxname{cpp_lib_start_lifetime_as}@                 202207L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_starts_ends_with}@                  201711L // also in \libheader{string}, \libheader{string_view}
#define @\defnlibxname{cpp_lib_stdatomic_h}@                       202011L // also in \libheader{stdatomic.h}
#define @\defnlibxname{cpp_lib_string_contains}@                   202011L // also in \libheader{string}, \libheader{string_view}
#define @\defnlibxname{cpp_lib_string_resize_and_overwrite}@       202110L // also in \libheader{string}
#define @\defnlibxname{cpp_lib_string_subview}@                    202506L // also in \libheader{string}, \libheader{string_view}
#define @\defnlibxname{cpp_lib_string_udls}@                       201304L // also in \libheader{string}
#define @\defnlibxname{cpp_lib_string_view}@                       202403L // also in \libheader{string}, \libheader{string_view}
#define @\defnlibxname{cpp_lib_submdspan}@                         202511L // freestanding, also in \libheader{mdspan}
#define @\defnlibxname{cpp_lib_syncbuf}@                           201803L // also in \libheader{iosfwd}, \libheader{syncstream}
#define @\defnlibxname{cpp_lib_task}@                              202506L // also in \libheader{execution}
#define @\defnlibxname{cpp_lib_text_encoding}@                     202306L // also in \libheader{text_encoding}
#define @\defnlibxname{cpp_lib_three_way_comparison}@              201907L // freestanding, also in \libheader{compare}
#define @\defnlibxname{cpp_lib_to_address}@                        201711L // freestanding, also in \libheader{memory}
#define @\defnlibxname{cpp_lib_to_array}@                          201907L // freestanding, also in \libheader{array}
#define @\defnlibxname{cpp_lib_to_chars}@                          202306L // also in \libheader{charconv}
#define @\defnlibxname{cpp_lib_to_string}@                         202306L // also in \libheader{string}
#define @\defnlibxname{cpp_lib_to_underlying}@                     202102L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_transformation_trait_aliases}@      201304L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_transparent_operators}@             201510L
  // freestanding, also in \libheader{memory}, \libheader{functional}
#define @\defnlibxname{cpp_lib_tuple_element_t}@                   201402L // freestanding, also in \libheader{tuple}
#define @\defnlibxname{cpp_lib_tuple_like}@                        202311L
  // also in \libheader{utility}, \libheader{tuple}, \libheader{map}, \libheader{unordered_map}
#define @\defnlibxname{cpp_lib_tuples_by_type}@                    201304L // freestanding, also in \libheader{utility}, \libheader{tuple}
#define @\defnlibxname{cpp_lib_type_identity}@                     201806L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_type_order}@                        202506L // also in \libheader{compare}
#define @\defnlibxname{cpp_lib_type_trait_variable_templates}@     201510L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_uncaught_exceptions}@               201411L // freestanding, also in \libheader{exception}
#define @\defnlibxname{cpp_lib_unordered_map_try_emplace}@         201411L // also in \libheader{unordered_map}
#define @\defnlibxname{cpp_lib_unreachable}@                       202202L // freestanding, also in \libheader{utility}
#define @\defnlibxname{cpp_lib_unwrap_ref}@                        201811L // freestanding, also in \libheader{type_traits}
#define @\defnlibxname{cpp_lib_valarray}@                          202511L // also in \libheader{valarray}
#define @\defnlibxname{cpp_lib_variant}@                           202306L // also in \libheader{variant}
#define @\defnlibxname{cpp_lib_void_t}@                            201411L // freestanding, also in \libheader{type_traits}
\end{codeblock}

\pnum
Additionally, each of the following macros is defined in a hardened implementation:
\begin{codeblock}
#define @\defnlibxname{cpp_lib_hardened_array}@                    202502L // also in \libheader{array}
#define @\defnlibxname{cpp_lib_hardened_basic_stacktrace}@         202506L // also in \libheader{stacktrace}
#define @\defnlibxname{cpp_lib_hardened_basic_string}@             202502L // also in \libheader{string}
#define @\defnlibxname{cpp_lib_hardened_basic_string_view}@        202502L // also in \libheader{string_view}
#define @\defnlibxname{cpp_lib_hardened_bitset}@                   202502L // also in \libheader{bitset}
#define @\defnlibxname{cpp_lib_hardened_common_iterator}@          202506L // also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_hardened_counted_iterator}@         202506L // also in \libheader{iterator}
#define @\defnlibxname{cpp_lib_hardened_deque}@                    202502L // also in \libheader{deque}
#define @\defnlibxname{cpp_lib_hardened_expected}@                 202502L // also in \libheader{expected}
#define @\defnlibxname{cpp_lib_hardened_forward_list}@             202502L // also in \libheader{forward_list}
#define @\defnlibxname{cpp_lib_hardened_inplace_vector}@           202502L // also in \libheader{inplace_vector}
#define @\defnlibxname{cpp_lib_hardened_list}@                     202502L // also in \libheader{list}
#define @\defnlibxname{cpp_lib_hardened_mdspan}@                   202502L // also in \libheader{mdspan}
#define @\defnlibxname{cpp_lib_hardened_optional}@                 202502L // also in \libheader{optional}
#define @\defnlibxname{cpp_lib_hardened_shared_ptr_array}@         202506L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_hardened_span}@                     202502L // also in \libheader{span}
#define @\defnlibxname{cpp_lib_hardened_valarray}@                 202502L // also in \libheader{valarray}
#define @\defnlibxname{cpp_lib_hardened_vector}@                   202502L // also in \libheader{vector}
#define @\defnlibxname{cpp_lib_hardened_view_interface}@           202506L // also in \libheader{ranges}
\end{codeblock}

\pnum
The macro \xname{cpp_lib_freestanding_operator_new} is defined to
the integer literal \tcode{202306L}
if all the default versions of the replaceable global allocation functions meet
the requirements of a hosted implementation, and
to the integer literal \tcode{0} otherwise\iref{new.delete}.

\pnum
\recommended
Freestanding implementations should only define a macro from \libheader{version}
if the implementation provides the corresponding facility in its entirety.

\pnum
\recommended
A non-hardened implementation should not define macros from \libheader{version}
required for hardened implementations.

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

\indexheader{limits}%
\indextext{\idxcode{numeric_limits}}%
\indexlibraryglobal{numeric_limits}%
\indexlibraryglobal{float_round_style}%

\begin{codeblock}
// all freestanding
namespace std {
  // \ref{round.style}, enumeration \tcode{float_round_style}
  enum float_round_style;

  // \ref{numeric.limits}, class template \tcode{numeric_limits}
  template<class T> class numeric_limits;

  template<class T> class numeric_limits<const T>;
  template<class T> class numeric_limits<volatile T>;
  template<class T> class numeric_limits<const volatile T>;

  template<> class numeric_limits<bool>;

  template<> class numeric_limits<char>;
  template<> class numeric_limits<signed char>;
  template<> class numeric_limits<unsigned char>;
  template<> class numeric_limits<char8_t>;
  template<> class numeric_limits<char16_t>;
  template<> class numeric_limits<char32_t>;
  template<> class numeric_limits<wchar_t>;

  template<> class numeric_limits<short>;
  template<> class numeric_limits<int>;
  template<> class numeric_limits<long>;
  template<> class numeric_limits<long long>;
  template<> class numeric_limits<unsigned short>;
  template<> class numeric_limits<unsigned int>;
  template<> class numeric_limits<unsigned long>;
  template<> class numeric_limits<unsigned long long>;

  template<> class numeric_limits<float>;
  template<> class numeric_limits<double>;
  template<> class numeric_limits<long double>;
}
\end{codeblock}

\rSec2[round.style]{Enum \tcode{float_round_style}}

\indexlibraryglobal{float_round_style}%
\begin{codeblock}
namespace std {
  enum float_round_style {
    round_indeterminate       = -1,
    round_toward_zero         =  0,
    round_to_nearest          =  1,
    round_toward_infinity     =  2,
    round_toward_neg_infinity =  3
  };
}
\end{codeblock}

\pnum
The rounding mode for floating-point arithmetic is characterized by the
values:
\begin{itemize}
\item
\indexlibraryglobal{round_indeterminate}%
\tcode{round_indeterminate}
if the rounding style is indeterminable
\item
\indexlibraryglobal{round_toward_zero}%
\tcode{round_toward_zero}
if the rounding style is toward zero
\item
\indexlibraryglobal{round_to_nearest}%
\tcode{round_to_nearest}
if the rounding style is to the nearest representable value
\item
\indexlibraryglobal{round_toward_infinity}%
\tcode{round_toward_infinity}
if the rounding style is toward infinity
\item
\indexlibraryglobal{round_toward_neg_infinity}%
\tcode{round_toward_neg_infinity}
if the rounding style is toward negative infinity
\end{itemize}

\rSec2[numeric.limits]{Class template \tcode{numeric_limits}}

\rSec3[numeric.limits.general]{General}

\pnum
The
\indexlibraryglobal{numeric_limits}%
\tcode{numeric_limits}
class template provides a \Cpp{} program with information about various properties of
the implementation's representation of the
arithmetic types.

\indexlibraryglobal{numeric_limits}%
\begin{codeblock}
namespace std {
  template<class T> class numeric_limits {
  public:
    static constexpr bool is_specialized = false;
    static constexpr T min() noexcept { return T(); }
    static constexpr T max() noexcept { return T(); }
    static constexpr T lowest() noexcept { return T(); }

    static constexpr int  digits = 0;
    static constexpr int  digits10 = 0;
    static constexpr int  max_digits10 = 0;
    static constexpr bool is_signed = false;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact = false;
    static constexpr int  radix = 0;
    static constexpr T epsilon() noexcept { return T(); }
    static constexpr T round_error() noexcept { return T(); }

    static constexpr int  min_exponent = 0;
    static constexpr int  min_exponent10 = 0;
    static constexpr int  max_exponent = 0;
    static constexpr int  max_exponent10 = 0;

    static constexpr bool has_infinity = false;
    static constexpr bool has_quiet_NaN = false;
    static constexpr bool has_signaling_NaN = false;
    static constexpr T infinity() noexcept { return T(); }
    static constexpr T quiet_NaN() noexcept { return T(); }
    static constexpr T signaling_NaN() noexcept { return T(); }
    static constexpr T denorm_min() noexcept { return T(); }

    static constexpr bool is_iec559 = false;
    static constexpr bool is_bounded = false;
    static constexpr bool is_modulo = false;

    static constexpr bool traps = false;
    static constexpr bool tinyness_before = false;
    static constexpr float_round_style round_style = round_toward_zero;
  };
}
\end{codeblock}

\pnum
For all members declared
\keyword{static} \keyword{constexpr}
in the
\tcode{numeric_limits}
template, specializations shall define these values in such a way
that they are usable as
constant expressions.

\pnum
For the
\tcode{numeric_limits}
primary template, all data members are value-initialized and all
member functions return a value-initialized object.
\begin{note}
This means all members have zero or \tcode{false} values
unless \tcode{numeric_limits} is specialized for a type.
\end{note}

\pnum
Specializations shall be provided for each
arithmetic type,
both floating-point and integer, including
\tcode{bool}.
The member
\tcode{is_specialized}
shall be
\tcode{true}
for all such specializations of
\tcode{numeric_limits}.

\pnum
The value of each member of a specialization of
\tcode{numeric_limits} on a cv-qualified type
\tcode{cv T} shall be equal to the value of the corresponding member of
the specialization on the unqualified type \tcode{T}.

\pnum
Non-arithmetic standard types, such as
\tcode{complex<T>}\iref{complex}, shall not have specializations.

\rSec3[numeric.limits.members]{\tcode{numeric_limits} members}

\pnum
\indextext{signal-safe!\idxcode{numeric_limits} members}%
Each member function defined in this subclause is signal-safe\iref{support.signal}.

\indexlibrarymember{min}{numeric_limits}%
\begin{itemdecl}
static constexpr T min() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Minimum finite value.
\begin{footnote}
Equivalent to \tcode{CHAR_MIN}, \tcode{SHRT_MIN},
\tcode{FLT_MIN}, \tcode{DBL_MIN}, etc.
\end{footnote}

\indextext{number!subnormal}%
\pnum
For floating-point types with subnormal numbers, returns the minimum positive
normalized value.

\pnum
Meaningful for all specializations in which
\tcode{is_bounded != false},
or
\tcode{is_bounded == false \&\& is_signed == false}.
\end{itemdescr}

\indexlibrarymember{max}{numeric_limits}%
\begin{itemdecl}
static constexpr T max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Maximum finite value.
\begin{footnote}
Equivalent to \tcode{CHAR_MAX}, \tcode{SHRT_MAX},
\tcode{FLT_MAX}, \tcode{DBL_MAX}, etc.
\end{footnote}

\pnum
Meaningful for all specializations in which
\tcode{is_bounded != false}.
\end{itemdescr}

\indexlibrarymember{lowest}{numeric_limits}%
\begin{itemdecl}
static constexpr T lowest() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
A finite value \tcode{x} such that there is no other finite
value \tcode{y} where \tcode{y < x}.
\begin{footnote}
\tcode{lowest()} is necessary because not all
floating-point representations have a smallest (most negative) value that is
the negative of the largest (most positive) finite value.
\end{footnote}

\pnum
Meaningful for all specializations in which \tcode{is_bounded != false}.
\end{itemdescr}

\indexlibrarymember{digits}{numeric_limits}%
\begin{itemdecl}
static constexpr int digits;
\end{itemdecl}

\begin{itemdescr}
\pnum
Number of
\tcode{radix}
digits that can be represented without change.

\pnum
For integer types, the number of non-sign bits in the representation.

\pnum
For floating-point types, the number of \tcode{radix} digits in the
significand.
\begin{footnote}
Equivalent to \tcode{FLT_MANT_DIG}, \tcode{DBL_MANT_DIG},
\tcode{LDBL_MANT_DIG}.
\end{footnote}
\end{itemdescr}

\indexlibrarymember{digits10}{numeric_limits}%
\begin{itemdecl}
static constexpr int digits10;
\end{itemdecl}

\begin{itemdescr}
\pnum
Number of base 10 digits that can be represented without
change.
\begin{footnote}
Equivalent to \tcode{FLT_DIG}, \tcode{DBL_DIG},
\tcode{LDBL_DIG}.
\end{footnote}

\pnum
Meaningful for all specializations in which
\tcode{is_bounded != false}.
\end{itemdescr}

\indexlibrarymember{max_digits10}{numeric_limits}%
\begin{itemdecl}
static constexpr int max_digits10;
\end{itemdecl}

\begin{itemdescr}
\pnum
Number of base 10 digits required to ensure that values which
differ are always differentiated.

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{is_signed}{numeric_limits}%
\begin{itemdecl}
static constexpr bool is_signed;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type is signed.

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{is_integer}{numeric_limits}%
\begin{itemdecl}
static constexpr bool is_integer;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type is integer.

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{is_exact}{numeric_limits}%
\begin{itemdecl}
static constexpr bool is_exact;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type uses an exact representation.
All integer types are exact, but not all exact types are integer.
For example, rational and fixed-exponent representations are exact but not integer.

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{radix}{numeric_limits}%
\begin{itemdecl}
static constexpr int radix;
\end{itemdecl}

\begin{itemdescr}
\pnum
For floating-point types, specifies the base or radix of the exponent representation
(often 2).
\begin{footnote}
Equivalent to \tcode{FLT_RADIX}.
\end{footnote}

\pnum
For integer types, specifies the base of the
representation.
\begin{footnote}
Distinguishes types with bases other than 2 (e.g., BCD).
\end{footnote}

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{epsilon}{numeric_limits}%
\begin{itemdecl}
static constexpr T epsilon() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Machine epsilon:  the difference between 1 and the least value greater than 1
that is representable.
\begin{footnote}
Equivalent to \tcode{FLT_EPSILON}, \tcode{DBL_EPSILON}, \tcode{LDBL_EPSILON}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{round_error}{numeric_limits}%
\begin{itemdecl}
static constexpr T round_error() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Measure of the maximum rounding error.
\end{itemdescr}

\indexlibrarymember{min_exponent}{numeric_limits}%
\begin{itemdecl}
static constexpr int min_exponent;
\end{itemdecl}

\begin{itemdescr}
\pnum
Minimum negative integer such that
\tcode{radix}
raised to the power of one less than that integer is a normalized floating-point
number.
\begin{footnote}
Equivalent to \tcode{FLT_MIN_EXP}, \tcode{DBL_MIN_EXP},
\tcode{LDBL_MIN_EXP}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{min_exponent10}{numeric_limits}%
\begin{itemdecl}
static constexpr int min_exponent10;
\end{itemdecl}

\begin{itemdescr}
\pnum
Minimum negative integer such that 10 raised to that power is in the range
of normalized floating-point numbers.
\begin{footnote}
Equivalent to
\tcode{FLT_MIN_10_EXP}, \tcode{DBL_MIN_10_EXP}, \tcode{LDBL_MIN_10_EXP}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{max_exponent}{numeric_limits}%
\begin{itemdecl}
static constexpr int max_exponent;
\end{itemdecl}

\begin{itemdescr}
\pnum
Maximum positive integer such that
\tcode{radix}
raised to the power one less than that integer is a representable finite
floating-point number.
\begin{footnote}
Equivalent to \tcode{FLT_MAX_EXP},
\tcode{DBL_MAX_EXP}, \tcode{LDBL_MAX_EXP}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{max_exponent10}{numeric_limits}%
\begin{itemdecl}
static constexpr int max_exponent10;
\end{itemdecl}

\begin{itemdescr}
\pnum
Maximum positive integer such that 10 raised to that power is in the
range of representable finite floating-point numbers.
\begin{footnote}
Equivalent to
\tcode{FLT_MAX_10_EXP}, \tcode{DBL_MAX_10_EXP}, \tcode{LDBL_MAX_10_EXP}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{has_infinity}{numeric_limits}%
\begin{itemdecl}
static constexpr bool has_infinity;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type has a representation for positive infinity.

\pnum
Meaningful for all floating-point types.

\pnum
Shall be
\tcode{true}
for all specializations in which
\tcode{is_iec559 != false}.
\end{itemdescr}

\indexlibrarymember{has_quiet_NaN}{numeric_limits}%
\begin{itemdecl}
static constexpr bool has_quiet_NaN;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type has a representation for a quiet (non-signaling) ``Not a
Number''.

\pnum
Meaningful for all floating-point types.

\pnum
Shall be
\tcode{true}
for all specializations in which
\tcode{is_iec559 != false}.
\end{itemdescr}

\indexlibrarymember{has_signaling_NaN}{numeric_limits}%
\begin{itemdecl}
static constexpr bool has_signaling_NaN;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type has a representation for a signaling ``Not a Number''.

\pnum
Meaningful for all floating-point types.

\pnum
Shall be
\tcode{true}
for all specializations in which
\tcode{is_iec559 != false}.
\end{itemdescr}

\indexlibrarymember{infinity}{numeric_limits}%
\begin{itemdecl}
static constexpr T infinity() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Representation of positive infinity, if available.

\pnum
Meaningful for all specializations for which
\tcode{has_infinity != false}.
Required in specializations for which
\tcode{is_iec559 != false}.
\end{itemdescr}

\indexlibrarymember{quiet_NaN}{numeric_limits}%
\begin{itemdecl}
static constexpr T quiet_NaN() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Representation of a quiet ``Not a Number'', if available.

\pnum
Meaningful for all specializations for which
\tcode{has_quiet_NaN != false}.
Required in specializations for which
\tcode{is_iec559 != false}.
\end{itemdescr}

\indexlibrarymember{signaling_NaN}{numeric_limits}%
\begin{itemdecl}
static constexpr T signaling_NaN() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Representation of a signaling ``Not a Number'', if available.

\pnum
Meaningful for all specializations for which
\tcode{has_signaling_NaN != false}.
Required in specializations for which
\tcode{is_iec559 != false}.
\end{itemdescr}

\indexlibrarymember{denorm_min}{numeric_limits}%
\begin{itemdecl}
static constexpr T denorm_min() noexcept;
\end{itemdecl}

\begin{itemdescr}
\indextext{number!subnormal}%
\pnum
Minimum positive subnormal value, if available.
Otherwise, minimum positive normalized value.

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{is_iec559}{numeric_limits}%
\begin{itemdecl}
static constexpr bool is_iec559;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if and only if the type adheres to \IsoFloatUndated{}.
\begin{footnote}
\IsoFloatUndated{}:2020 is the same as IEEE 754-2019.
\end{footnote}
\begin{note}
The value is \tcode{true} for any of the types
\tcode{float16_t}, \tcode{float32_t}, \tcode{float64_t}, or \tcode{float128_t},
if present\iref{basic.extended.fp}.
\end{note}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{is_bounded}{numeric_limits}%
\begin{itemdecl}
static constexpr bool is_bounded;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the set of values representable by the type is finite.
\begin{note}
All fundamental types\iref{basic.fundamental} are bounded. This member would be \tcode{false} for arbitrary
precision types.
\end{note}

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{is_modulo}{numeric_limits}%
\begin{itemdecl}
static constexpr bool is_modulo;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true} if the type is modulo.
A type is modulo if, for any operation involving \tcode{+}, \tcode{-}, or
\tcode{*} on values of that type whose result would fall outside the range
\crange{min()}{max()}, the value returned differs from the true value by an
integer multiple of \tcode{max() - min() + 1}.

\pnum
\begin{example}
\tcode{is_modulo} is \tcode{false} for signed integer types\iref{basic.fundamental}
unless an implementation, as an extension to this document,
defines signed integer overflow to wrap.
\end{example}

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{traps}{numeric_limits}%
\begin{itemdecl}
static constexpr bool traps;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true}
if, at the start of the program, there exists a value of the type that would cause
an arithmetic operation using that value to trap.

\pnum
Meaningful for all specializations.
\end{itemdescr}

\indexlibrarymember{tinyness_before}{numeric_limits}%
\begin{itemdecl}
static constexpr bool tinyness_before;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{true}
if tinyness is detected before rounding.
\begin{footnote}
Refer to
\IsoFloatUndated{}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
\end{itemdescr}

\indexlibrarymember{round_style}{numeric_limits}%
\begin{itemdecl}
static constexpr float_round_style round_style;
\end{itemdecl}

\begin{itemdescr}
\pnum
The rounding style for the type.
\begin{footnote}
Equivalent to \tcode{FLT_ROUNDS}.
\end{footnote}

\pnum
Meaningful for all floating-point types.
Specializations for integer types shall return
\tcode{round_toward_zero}.
\end{itemdescr}

\rSec3[numeric.special]{\tcode{numeric_limits} specializations}

\pnum
All members shall be provided for all specializations.
However, many values are only required to be meaningful under certain
conditions
(for example,
\tcode{epsilon()}
is only meaningful if
\tcode{is_integer}
is
\tcode{false}).
Any value that is not ``meaningful'' shall be set to 0 or
\tcode{false}.

\pnum
\begin{example}
\begin{codeblock}
namespace std {
  template<> class numeric_limits<float> {
  public:
    static constexpr bool is_specialized = true;

    static constexpr float min() noexcept { return 1.17549435E-38F; }
    static constexpr float max() noexcept { return 3.40282347E+38F; }
    static constexpr float lowest() noexcept { return -3.40282347E+38F; }

    static constexpr int digits   = 24;
    static constexpr int digits10 =  6;
    static constexpr int max_digits10 =  9;

    static constexpr bool is_signed  = true;
    static constexpr bool is_integer = false;
    static constexpr bool is_exact   = false;

    static constexpr int radix = 2;
    static constexpr float epsilon() noexcept     { return 1.19209290E-07F; }
    static constexpr float round_error() noexcept { return 0.5F; }

    static constexpr int min_exponent   = -125;
    static constexpr int min_exponent10 = - 37;
    static constexpr int max_exponent   = +128;
    static constexpr int max_exponent10 = + 38;

    static constexpr bool has_infinity      = true;
    static constexpr bool has_quiet_NaN     = true;
    static constexpr bool has_signaling_NaN = true;

    static constexpr float infinity()      noexcept { return @\textit{value}@; }
    static constexpr float quiet_NaN()     noexcept { return @\textit{value}@; }
    static constexpr float signaling_NaN() noexcept { return @\textit{value}@; }
    static constexpr float denorm_min()    noexcept { return min(); }

    static constexpr bool is_iec559  = true;
    static constexpr bool is_bounded = true;
    static constexpr bool is_modulo  = false;
    static constexpr bool traps      = true;
    static constexpr bool tinyness_before = true;

    static constexpr float_round_style round_style = round_to_nearest;
  };
}
\end{codeblock}
\end{example}

\pnum
The specialization for
\tcode{bool}
shall be provided as follows:
\indexlibraryglobal{numeric_limits<bool>}%
\begin{codeblock}
namespace std {
  template<> class numeric_limits<bool> {
  public:
    static constexpr bool is_specialized = true;
    static constexpr bool min() noexcept { return false; }
    static constexpr bool max() noexcept { return true; }
    static constexpr bool lowest() noexcept { return false; }

    static constexpr int  digits = 1;
    static constexpr int  digits10 = 0;
    static constexpr int  max_digits10 = 0;

    static constexpr bool is_signed = false;
    static constexpr bool is_integer = true;
    static constexpr bool is_exact = true;
    static constexpr int  radix = 2;
    static constexpr bool epsilon() noexcept { return 0; }
    static constexpr bool round_error() noexcept { return 0; }

    static constexpr int  min_exponent = 0;
    static constexpr int  min_exponent10 = 0;
    static constexpr int  max_exponent = 0;
    static constexpr int  max_exponent10 = 0;

    static constexpr bool has_infinity = false;
    static constexpr bool has_quiet_NaN = false;
    static constexpr bool has_signaling_NaN = false;
    static constexpr bool infinity() noexcept { return 0; }
    static constexpr bool quiet_NaN() noexcept { return 0; }
    static constexpr bool signaling_NaN() noexcept { return 0; }
    static constexpr bool denorm_min() noexcept { return 0; }

    static constexpr bool is_iec559 = false;
    static constexpr bool is_bounded = true;
    static constexpr bool is_modulo = false;

    static constexpr bool traps = false;
    static constexpr bool tinyness_before = false;
    static constexpr float_round_style round_style = round_toward_zero;
  };
}
\end{codeblock}

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

\indexheader{climits}%
\begin{codeblock}
// all freestanding
#define @\libmacro{BOOL_WIDTH}@ @\seebelow@
#define @\libmacro{CHAR_BIT}@ @\seebelow@
#define @\libmacro{CHAR_WIDTH}@ @\seebelow@
#define @\libmacro{SCHAR_WIDTH}@ @\seebelow@
#define @\libmacro{UCHAR_WIDTH}@ @\seebelow@
#define @\libmacro{USHRT_WIDTH}@ @\seebelow@
#define @\libmacro{SHRT_WIDTH}@ @\seebelow@
#define @\libmacro{UINT_WIDTH}@ @\seebelow@
#define @\libmacro{INT_WIDTH}@ @\seebelow@
#define @\libmacro{ULONG_WIDTH}@ @\seebelow@
#define @\libmacro{LONG_WIDTH}@ @\seebelow@
#define @\libmacro{ULLONG_WIDTH}@ @\seebelow@
#define @\libmacro{LLONG_WIDTH}@ @\seebelow@
#define @\libmacro{SCHAR_MIN}@ @\seebelow@
#define @\libmacro{SCHAR_MAX}@ @\seebelow@
#define @\libmacro{UCHAR_MAX}@ @\seebelow@
#define @\libmacro{CHAR_MIN}@ @\seebelow@
#define @\libmacro{CHAR_MAX}@ @\seebelow@
#define @\libmacro{MB_LEN_MAX}@ @\seebelow@
#define @\libmacro{SHRT_MIN}@ @\seebelow@
#define @\libmacro{SHRT_MAX}@ @\seebelow@
#define @\libmacro{USHRT_MAX}@ @\seebelow@
#define @\libmacro{INT_MIN}@ @\seebelow@
#define @\libmacro{INT_MAX}@ @\seebelow@
#define @\libmacro{UINT_MAX}@ @\seebelow@
#define @\libmacro{LONG_MIN}@ @\seebelow@
#define @\libmacro{LONG_MAX}@ @\seebelow@
#define @\libmacro{ULONG_MAX}@ @\seebelow@
#define @\libmacro{LLONG_MIN}@ @\seebelow@
#define @\libmacro{LLONG_MAX}@ @\seebelow@
#define @\libmacro{ULLONG_MAX}@ @\seebelow@
\end{codeblock}

\pnum
The header \libheader{climits} defines all macros the same as
the C standard library header \libheader{limits.h},
except that it does not define the macro \tcode{BITINT_MAXWIDTH}.
\begin{note}
Except for the \tcode{WIDTH} macros, \tcode{CHAR_BIT}, and \tcode{MB_LEN_MAX},
a macro referring to
an integer type \tcode{T} defines a constant whose type is the promoted
type of \tcode{T}\iref{conv.prom}.
\end{note}

\xrefc{5.3.5.3.2}

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

\indexheader{cfloat}%
\begin{codeblock}
// all freestanding
#define __STDC_VERSION_FLOAT_H__ 202311L

#define @\libmacro{FLT_ROUNDS}@ @\seebelow@
#define @\libmacro{FLT_EVAL_METHOD}@ @\seebelow@
#define @\libmacro{FLT_RADIX}@ @\seebelow@
#define @\libmacro{INFINITY}@ @\seebelow@
#define @\libmacro{NAN}@ @\seebelow@
#define @\libmacro{FLT_SNAN}@ @\seebelow@
#define @\libmacro{DBL_SNAN}@ @\seebelow@
#define @\libmacro{LDBL_SNAN}@ @\seebelow@
#define @\libmacro{FLT_MANT_DIG}@ @\seebelow@
#define @\libmacro{DBL_MANT_DIG}@ @\seebelow@
#define @\libmacro{LDBL_MANT_DIG}@ @\seebelow@
#define @\libmacro{FLT_DECIMAL_DIG}@ @\seebelow@
#define @\libmacro{DBL_DECIMAL_DIG}@ @\seebelow@
#define @\libmacro{LDBL_DECIMAL_DIG}@ @\seebelow@
#define @\libmacro{FLT_DIG}@ @\seebelow@
#define @\libmacro{DBL_DIG}@ @\seebelow@
#define @\libmacro{LDBL_DIG}@ @\seebelow@
#define @\libmacro{FLT_MIN_EXP}@ @\seebelow@
#define @\libmacro{DBL_MIN_EXP}@ @\seebelow@
#define @\libmacro{LDBL_MIN_EXP}@ @\seebelow@
#define @\libmacro{FLT_MIN_10_EXP}@ @\seebelow@
#define @\libmacro{DBL_MIN_10_EXP}@ @\seebelow@
#define @\libmacro{LDBL_MIN_10_EXP}@ @\seebelow@
#define @\libmacro{FLT_MAX_EXP}@ @\seebelow@
#define @\libmacro{DBL_MAX_EXP}@ @\seebelow@
#define @\libmacro{LDBL_MAX_EXP}@ @\seebelow@
#define @\libmacro{FLT_MAX_10_EXP}@ @\seebelow@
#define @\libmacro{DBL_MAX_10_EXP}@ @\seebelow@
#define @\libmacro{LDBL_MAX_10_EXP}@ @\seebelow@
#define @\libmacro{FLT_MAX}@ @\seebelow@
#define @\libmacro{DBL_MAX}@ @\seebelow@
#define @\libmacro{LDBL_MAX}@ @\seebelow@
#define @\libmacro{FLT_EPSILON}@ @\seebelow@
#define @\libmacro{DBL_EPSILON}@ @\seebelow@
#define @\libmacro{LDBL_EPSILON}@ @\seebelow@
#define @\libmacro{FLT_MIN}@ @\seebelow@
#define @\libmacro{DBL_MIN}@ @\seebelow@
#define @\libmacro{LDBL_MIN}@ @\seebelow@
#define @\libmacro{FLT_TRUE_MIN}@ @\seebelow@
#define @\libmacro{DBL_TRUE_MIN}@ @\seebelow@
#define @\libmacro{LDBL_TRUE_MIN}@ @\seebelow@
\end{codeblock}

\pnum
The header \libheader{cfloat} defines all macros the same as
the C standard library header \libheader{float.h}.

\xrefc{5.3.5.3.3}

\rSec1[support.arith.types]{Arithmetic types}

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

\pnum
The header \libheader{cstdint}
supplies integer types having specified widths, and
macros that specify limits of integer types.

\indexheader{cstdint}%
\indexlibraryglobal{int8_t}%
\indexlibraryglobal{int16_t}%
\indexlibraryglobal{int32_t}%
\indexlibraryglobal{int64_t}%
\indexlibraryglobal{int_fast8_t}%
\indexlibraryglobal{int_fast16_t}%
\indexlibraryglobal{int_fast32_t}%
\indexlibraryglobal{int_fast64_t}%
\indexlibraryglobal{int_least8_t}%
\indexlibraryglobal{int_least16_t}%
\indexlibraryglobal{int_least32_t}%
\indexlibraryglobal{int_least64_t}%
\indexlibraryglobal{intmax_t}%
\indexlibraryglobal{intptr_t}%
\indexlibraryglobal{uint8_t}%
\indexlibraryglobal{uint16_t}%
\indexlibraryglobal{uint32_t}%
\indexlibraryglobal{uint64_t}%
\indexlibraryglobal{uint_fast8_t}%
\indexlibraryglobal{uint_fast16_t}%
\indexlibraryglobal{uint_fast32_t}%
\indexlibraryglobal{uint_fast64_t}%
\indexlibraryglobal{uint_least8_t}%
\indexlibraryglobal{uint_least16_t}%
\indexlibraryglobal{uint_least32_t}%
\indexlibraryglobal{uint_least64_t}%
\indexlibraryglobal{uintmax_t}%
\indexlibraryglobal{uintptr_t}%
\indexlibraryglobal{INTN_MIN}%
\indexlibraryglobal{INTN_MAX}%
\indexlibraryglobal{UINTN_MAX}%
\indexlibraryglobal{INT_FASTN_MIN}%
\indexlibraryglobal{INT_FASTN_MAX}%
\indexlibraryglobal{UINT_FASTN_MAX}%
\indexlibraryglobal{INT_LEASTN_MIN}%
\indexlibraryglobal{INT_LEASTN_MAX}%
\indexlibraryglobal{UINT_LEASTN_MAX}%
\indexlibraryglobal{INTMAX_MIN}%
\indexlibraryglobal{INTMAX_MAX}%
\indexlibraryglobal{UINTMAX_MAX}%
\indexlibraryglobal{INTPTR_MIN}%
\indexlibraryglobal{INTPTR_MAX}%
\indexlibraryglobal{UINTPTR_MAX}%
\indexlibraryglobal{PTRDIFF_MIN}%
\indexlibraryglobal{PTRDIFF_MAX}%
\indexlibraryglobal{SIZE_MAX}%
\indexlibraryglobal{SIG_ATOMIC_MIN}%
\indexlibraryglobal{SIG_ATOMIC_MAX}%
\indexlibraryglobal{WCHAR_MAX}%
\indexlibraryglobal{WCHAR_MIN}%
\indexlibraryglobal{WINT_MIN}%
\indexlibraryglobal{WINT_MAX}%
\indexlibraryglobal{INTN_C}%
\indexlibraryglobal{UINTN_C}%
\indexlibraryglobal{INTMAX_C}%
\indexlibraryglobal{UINTMAX_C}%
\begin{codeblock}
// all freestanding
#define __STDC_VERSION_STDINT_H__ 202311L

namespace std {
  using int8_t         = @\textit{signed integer type}@;   // optional
  using int16_t        = @\textit{signed integer type}@;   // optional
  using int32_t        = @\textit{signed integer type}@;   // optional
  using int64_t        = @\textit{signed integer type}@;   // optional
  using int@\placeholdernc{N}@_t         = @\seebelow@;             // optional

  using int_fast8_t    = @\textit{signed integer type}@;
  using int_fast16_t   = @\textit{signed integer type}@;
  using int_fast32_t   = @\textit{signed integer type}@;
  using int_fast64_t   = @\textit{signed integer type}@;
  using int_fast@\placeholdernc{N}@_t    = @\seebelow@;             // optional

  using int_least8_t   = @\textit{signed integer type}@;
  using int_least16_t  = @\textit{signed integer type}@;
  using int_least32_t  = @\textit{signed integer type}@;
  using int_least64_t  = @\textit{signed integer type}@;
  using int_least@\placeholdernc{N}@_t   = @\seebelow@;             // optional

  using intmax_t       = @\textit{signed integer type}@;
  using intptr_t       = @\textit{signed integer type}@;   // optional

  using uint8_t        = @\textit{unsigned integer type}@; // optional
  using uint16_t       = @\textit{unsigned integer type}@; // optional
  using uint32_t       = @\textit{unsigned integer type}@; // optional
  using uint64_t       = @\textit{unsigned integer type}@; // optional
  using uint@\placeholdernc{N}@_t        = @\seebelow@;             // optional

  using uint_fast8_t   = @\textit{unsigned integer type}@;
  using uint_fast16_t  = @\textit{unsigned integer type}@;
  using uint_fast32_t  = @\textit{unsigned integer type}@;
  using uint_fast64_t  = @\textit{unsigned integer type}@;
  using uint_fast@\placeholdernc{N}@_t   = @\seebelow@;             // optional

  using uint_least8_t  = @\textit{unsigned integer type}@;
  using uint_least16_t = @\textit{unsigned integer type}@;
  using uint_least32_t = @\textit{unsigned integer type}@;
  using uint_least64_t = @\textit{unsigned integer type}@;
  using uint_least@\placeholdernc{N}@_t  = @\seebelow@;             // optional

  using uintmax_t      = @\textit{unsigned integer type}@;
  using uintptr_t      = @\textit{unsigned integer type}@; // optional
}

#define INT@\placeholdernc{N}@_MIN          @\seebelow@
#define INT@\placeholdernc{N}@_MAX          @\seebelow@
#define UINT@\placeholdernc{N}@_MAX         @\seebelow@
#define INT@\placeholdernc{N}@_WIDTH        @\seebelow@
#define UINT@\placeholdernc{N}@_WIDTH       @\seebelow@

#define INT_FAST@\placeholdernc{N}@_MIN     @\seebelow@
#define INT_FAST@\placeholdernc{N}@_MAX     @\seebelow@
#define UINT_FAST@\placeholdernc{N}@_MAX    @\seebelow@
#define INT_FAST@\placeholdernc{N}@_WIDTH   @\seebelow@
#define UINT_FAST@\placeholdernc{N}@_WIDTH  @\seebelow@

#define INT_LEAST@\placeholdernc{N}@_MIN    @\seebelow@
#define INT_LEAST@\placeholdernc{N}@_MAX    @\seebelow@
#define UINT_LEAST@\placeholdernc{N}@_MAX   @\seebelow@
#define INT_LEAST@\placeholdernc{N}@_WIDTH  @\seebelow@
#define UINT_LEAST@\placeholdernc{N}@_WIDTH @\seebelow@

#define INTMAX_MIN        @\seebelow@
#define INTMAX_MAX        @\seebelow@
#define UINTMAX_MAX       @\seebelow@
#define INTMAX_WIDTH      @\seebelow@
#define UINTMAX_WIDTH     @\seebelow@

#define INTPTR_MIN        @\seebelow@              // optional
#define INTPTR_MAX        @\seebelow@              // optional
#define UINTPTR_MAX       @\seebelow@              // optional
#define INTPTR_WIDTH      @\seebelow@              // optional
#define UINTPTR_WIDTH     @\seebelow@              // optional

#define PTRDIFF_MIN       @\seebelow@
#define PTRDIFF_MAX       @\seebelow@
#define PTRDIFF_WIDTH     @\seebelow@
#define SIZE_MAX          @\seebelow@
#define SIZE_WIDTH        @\seebelow@

#define SIG_ATOMIC_MIN    @\seebelow@
#define SIG_ATOMIC_MAX    @\seebelow@
#define SIG_ATOMIC_WIDTH  @\seebelow@

#define WCHAR_MIN         @\seebelow@
#define WCHAR_MAX         @\seebelow@
#define WCHAR_WIDTH       @\seebelow@

#define WINT_MIN          @\seebelow@
#define WINT_MAX          @\seebelow@
#define WINT_WIDTH        @\seebelow@

#define INT@\placeholdernc{N}@_C(value)     @\seebelow@
#define UINT@\placeholdernc{N}@_C(value)    @\seebelow@
#define INTMAX_C(value)   @\seebelow@
#define UINTMAX_C(value)  @\seebelow@
\end{codeblock}

\pnum
The header defines all types and macros the same as
the C standard library header \libheader{stdint.h}.
The types denoted by \tcode{intmax_t} and \tcode{uintmax_t}
are not required to be able to represent all values of extended integer types
wider than \tcode{long long} and \tcode{unsigned long long}, respectively.

\xrefc{7.22}

\pnum
All types that use the placeholder \placeholder{N}
are optional when \placeholder{N}
is not \tcode{8}, \tcode{16}, \tcode{32}, or \tcode{64}.
The exact-width types
\tcode{int\placeholdernc{N}_t} and \tcode{uint\placeholdernc{N}_t}
for \placeholder{N} = \tcode{8}, \tcode{16}, \tcode{32}, and \tcode{64}
are also optional;
however, if an implementation defines integer types
with the corresponding width and no padding bits,
it declares the corresponding \grammarterm{typedef-name}s.
Each of the macros listed in this subclause
is defined if and only if
the implementation declares the corresponding \grammarterm{typedef-name}.
\begin{note}
The macros \tcode{INT\placeholdernc{N}_C} and \tcode{UINT\placeholdernc{N}_C}
correspond to the \grammarterm{typedef-name}s
\tcode{int_least\placeholdernc{N}_t} and \tcode{uint_least\placeholdernc{N}_t},
respectively.
\end{note}

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

\pnum
The header \libheader{stdfloat} declares type aliases for
the optional extended floating-point types that are specified in
\ref{basic.extended.fp}.

\indexheader{stdfloat}%
\indexlibraryglobal{float16_t}%
\indexlibraryglobal{float32_t}%
\indexlibraryglobal{float64_t}%
\indexlibraryglobal{float128_t}%
\indexlibraryglobal{bfloat16_t}%
\begin{codeblock}
namespace std {
  #if defined(__STDCPP_FLOAT16_T__)
    using float16_t  = @\UNSP{\impldef{type of \tcode{std::float16_t}}}@;  // see \ref{basic.extended.fp}
  #endif
  #if defined(__STDCPP_FLOAT32_T__)
    using float32_t  = @\UNSP{\impldef{type of \tcode{std::float32_t}}}@;  // see \ref{basic.extended.fp}
  #endif
  #if defined(__STDCPP_FLOAT64_T__)
    using float64_t  = @\UNSP{\impldef{type of \tcode{std::float64_t}}}@;  // see \ref{basic.extended.fp}
  #endif
  #if defined(__STDCPP_FLOAT128_T__)
    using float128_t = @\UNSP{\impldef{type of \tcode{std::float128_t}}}@; // see \ref{basic.extended.fp}
  #endif
  #if defined(__STDCPP_BFLOAT16_T__)
    using bfloat16_t = @\UNSP{\impldef{type of \tcode{std::bfloat16_t}}}@; // see \ref{basic.extended.fp}
  #endif
}
\end{codeblock}

\rSec1[support.start.term]{Startup and termination}

\pnum
\begin{note}
The header \libheaderref{cstdlib}
declares the functions described in this subclause.
\end{note}

\indexlibraryglobal{_Exit}%
\begin{itemdecl}
[[noreturn]] void _Exit(int status) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
This function has the semantics specified in the C standard library.

\pnum
\remarks
The program is terminated without executing destructors for objects with automatic,
thread, or static storage duration and without calling functions passed to
\tcode{atexit()}\iref{basic.start.term}.
\indextext{signal-safe!\idxcode{_Exit}}%
The function \tcode{_Exit} is signal-safe\iref{support.signal}.
\end{itemdescr}

\indexlibraryglobal{abort}%
\begin{itemdecl}
[[noreturn]] void abort() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
This function has the semantics specified in the C standard library.

\pnum
\remarks
The program is terminated without executing destructors for objects of
automatic, thread, or static storage
duration and without calling functions passed to
\tcode{atexit()}\iref{basic.start.term}.
\indextext{signal-safe!\idxcode{abort}}%
The function \tcode{abort} is signal-safe\iref{support.signal}.
\end{itemdescr}

\indexlibraryglobal{atexit}%
\begin{itemdecl}
int atexit(@\placeholder{c-atexit-handler}@* f) noexcept;
int atexit(@\placeholder{atexit-handler}@* f) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The
\tcode{atexit()}
functions register the function pointed to by \tcode{f}
to be called without arguments at normal program termination.
It is unspecified whether a call to \tcode{atexit()} that does not
happen before\iref{intro.multithread} a call to \tcode{exit()} will succeed.
\begin{note}
The \tcode{atexit()} functions do not introduce a data
race\iref{res.on.data.races}.
\end{note}

\pnum
\implimits
The implementation shall support the registration of at least 32 functions.

\pnum
\returns
The
\tcode{atexit()}
function returns zero if the registration succeeds,
nonzero if it fails.
\end{itemdescr}

\indexlibraryglobal{exit}%
\begin{itemdecl}
[[noreturn]] void exit(int status);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\begin{itemize}
\item
First, objects with thread storage duration and associated with the current thread
are destroyed. Next, objects with static storage duration are destroyed
and functions registered by calling
\tcode{atexit}
are called.
\begin{footnote}
A function is called for every time it is registered.
\end{footnote}
See~\ref{basic.start.term} for the order of destructions and calls.
(Objects with automatic storage duration are not destroyed as a result of calling
\tcode{exit()}.)
\begin{footnote}
Objects with automatic storage duration are all destroyed in a program whose
\tcode{main} function\iref{basic.start.main}
contains no objects with automatic storage duration and executes the call to
\tcode{exit()}.
Control can be transferred directly to such a
\tcode{main} function
by throwing an exception that is caught in
\tcode{main}.
\end{footnote}

If a registered function invoked by \tcode{exit} exits via an exception,
the function \tcode{std::terminate} is invoked\iref{except.terminate}.%
\indexlibraryglobal{terminate}%

\item
Next, all open C streams (as mediated by the function
signatures declared in \libheaderref{cstdio})
with unwritten buffered data are flushed, all open C
streams are closed, and all files created by calling
\tcode{tmpfile()} are removed.

\item
Finally, control is returned to the host environment.
If \tcode{status} is zero or
\tcode{EXIT_SUCCESS},
an \impldef{exit status}
form of the status
\term{successful termination}
is returned.
If \tcode{status} is
\tcode{EXIT_FAILURE},
an \impldef{exit status} form of the status
\term{unsuccessful termination}
is returned.
Otherwise the status returned is \impldef{exit status}.
\begin{footnote}
The macros \tcode{EXIT_FAILURE} and \tcode{EXIT_SUCCESS}
are defined in \libheaderref{cstdlib}.
\end{footnote}
\end{itemize}
\end{itemdescr}

\indexlibraryglobal{at_quick_exit}%
\begin{itemdecl}
int at_quick_exit(@\placeholder{c-atexit-handler}@* f) noexcept;
int at_quick_exit(@\placeholder{atexit-handler}@* f) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The \tcode{at_quick_exit()} functions register the function pointed to by \tcode{f}
to be called without arguments when \tcode{quick_exit} is called.
It is unspecified whether a call to \tcode{at_quick_exit()} that does not
happen before\iref{intro.multithread} all calls to \tcode{quick_exit} will succeed.
\begin{note}
The
\tcode{at_quick_exit()} functions do not introduce a
data race\iref{res.on.data.races}.
\end{note}
\begin{note}
The order of registration could be indeterminate if \tcode{at_quick_exit} was called from more
than one thread.
\end{note}
\begin{note}
The
\tcode{at_quick_exit} registrations are distinct from the \tcode{atexit} registrations,
and applications might need to call both registration functions with the same argument.
\end{note}

\pnum
\implimits
The implementation shall support the registration of at least 32 functions.

\pnum
\returns
Zero if the registration succeeds, nonzero if it fails.
\end{itemdescr}

\indexlibraryglobal{quick_exit}%
\begin{itemdecl}
[[noreturn]] void quick_exit(int status) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Functions registered by calls to \tcode{at_quick_exit} are called in the
reverse order of their registration, except that a function shall be called after any
previously registered functions that had already been called at the time it was
registered. Objects shall not be destroyed as a result of calling \tcode{quick_exit}.
If a registered function invoked by \tcode{quick_exit} exits via an exception,
the function \tcode{std::terminate} is invoked\iref{except.terminate}.%
\indexlibraryglobal{terminate}
\begin{note}
A function registered via \tcode{at_quick_exit}
is invoked by the thread that calls \tcode{quick_exit},
which can be a different thread
than the one that registered it, so registered functions cannot rely on the identity
of objects with thread storage duration.
\end{note}
After calling registered functions, \tcode{quick_exit} shall call \tcode{_Exit(status)}.

\pnum
\remarks
\indextext{signal-safe!\idxcode{quick_exit}}%
The function \tcode{quick_exit} is signal-safe\iref{support.signal}
when the functions registered with \tcode{at_quick_exit} are.
\end{itemdescr}

\xrefc{7.24.5}

\rSec1[support.dynamic]{Dynamic memory management}

\rSec2[support.dynamic.general]{General}

\pnum
The header \libheaderdef{new} defines several
functions that manage the allocation of dynamic storage in a program.
It also defines components for reporting storage management errors.

\rSec2[new.syn]{Header \tcode{<new>} synopsis}
\begin{codeblock}
// all freestanding
namespace std {
  // \ref{alloc.errors}, storage allocation errors
  class bad_alloc;
  class bad_array_new_length;

  struct destroying_delete_t {
    explicit destroying_delete_t() = default;
  };
  inline constexpr destroying_delete_t destroying_delete{};

  // global \tcode{operator new} control%
  \indexlibraryglobal{align_val_t}%
  \indexlibraryglobal{destroying_delete_t}%
  \indexlibraryglobal{destroying_delete}%
  \indexlibraryglobal{nothrow_t}%
  \indexlibraryglobal{nothrow}
  enum class align_val_t : size_t {};

  struct nothrow_t { explicit nothrow_t() = default; };
  extern const nothrow_t nothrow;

  using new_handler = void (*)();
  new_handler get_new_handler() noexcept;
  new_handler set_new_handler(new_handler new_p) noexcept;

  // \ref{ptr.launder}, pointer optimization barrier
  template<class T> constexpr T* launder(T* p) noexcept;

  // \ref{hardware.interference}, hardware interference size
  inline constexpr size_t hardware_destructive_interference_size = @\impdef{}@;
  inline constexpr size_t hardware_constructive_interference_size = @\impdef{}@;
}

// \ref{new.delete}, storage allocation and deallocation
void* operator new(std::size_t size);
void* operator new(std::size_t size, std::align_val_t alignment);
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;

void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, std::size_t size) noexcept;
void operator delete(void* ptr, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;

void* operator new[](std::size_t size);
void* operator new[](std::size_t size, std::align_val_t alignment);
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, std::align_val_t alignment,
                     const std::nothrow_t&) noexcept;

void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;

constexpr void* operator new  (std::size_t size, void* ptr) noexcept;
constexpr void* operator new[](std::size_t size, void* ptr) noexcept;
void operator delete  (void* ptr, void*) noexcept;
void operator delete[](void* ptr, void*) noexcept;
\end{codeblock}

\rSec2[new.delete]{Storage allocation and deallocation}

\rSec3[new.delete.general]{General}

\pnum
Except where otherwise specified, the provisions of~\ref{basic.stc.dynamic}
apply to the library versions of \tcode{operator new} and \tcode{operator
delete}.
If the value of an alignment argument
passed to any of these functions
is not a valid alignment value,
the behavior is undefined.

\pnum
On freestanding implementations,
it is \impldef{whether freestanding default replaceable global allocation functions satisfy required behavior}
whether the default versions of the replaceable global allocation functions
satisfy the required behaviors
described in \ref{new.delete.single} and \ref{new.delete.array}.
\begin{note}
A freestanding implementation's default versions of
the replaceable global allocation functions
can cause undefined behavior when invoked.
During constant evaluation,
the behaviors of those default versions are irrelevant,
as those calls are omitted\iref{expr.new}.
\end{note}

\recommended
If any of the default versions of the replaceable global allocation functions
meet the requirements of a hosted implementation, they all should.

\rSec3[new.delete.single]{Single-object forms}

\indexlibrarymember{new}{operator}%
\begin{itemdecl}
void* operator new(std::size_t size);
void* operator new(std::size_t size, std::align_val_t alignment);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The
allocation functions\iref{basic.stc.dynamic.allocation}
called by a
\grammarterm{new-expression}\iref{expr.new}
to allocate
\tcode{size} bytes of storage.
The second form is called for a type with new-extended alignment, and
the first form is called otherwise.

\pnum
\required
Return a non-null pointer to suitably aligned storage\iref{basic.stc.dynamic},
or else throw a
\tcode{bad_alloc}
\indexlibraryglobal{bad_alloc}%
exception.
This requirement is binding on any replacement versions of these functions.

\pnum
\default

\begin{itemize}
\item
Executes a loop:
Within the loop, the function first attempts to allocate the requested storage.
Whether the attempt involves a call to the C standard library functions
\tcode{malloc} or \tcode{aligned_alloc}
is unspecified.
\indextext{unspecified}%
\item
Returns a pointer to the allocated storage if the attempt is successful.
Otherwise, if the
current \tcode{new_handler}\iref{get.new.handler} is
a null pointer value, throws
\tcode{bad_alloc}.
\item
Otherwise, the function calls the current
\tcode{new_handler} function\iref{new.handler}.
If the called function returns, the loop repeats.
\item
The loop terminates when an attempt to allocate the requested storage is
successful or when a called
\tcode{new_handler}
function does not return.
\end{itemize}

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
\end{itemdescr}

\indexlibrarymember{new}{operator}%
\begin{itemdecl}
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Same as above, except that these are called by a placement version of a
\grammarterm{new-expression}
when a \Cpp{} program prefers a null pointer result as an error indication,
instead of a
\tcode{bad_alloc}
exception.

\pnum
\required
Return a non-null pointer to suitably aligned storage\iref{basic.stc.dynamic},
or else return a null pointer.
Each of these nothrow versions of
\tcode{operator new}
returns a pointer obtained as if
acquired from the (possibly replaced)
corresponding non-placement function.
This requirement is binding on any replacement versions of these functions.

\pnum
\default
Calls \tcode{operator new(size)},
or \tcode{operator new(size, alignment)},
respectively.
If the call returns normally,
returns the result of that call.
Otherwise, returns a null pointer.

\pnum
\begin{example}
\begin{codeblock}
T* p1 = new T;                  // throws \tcode{bad_alloc} if it fails
T* p2 = new(nothrow) T;         // returns \keyword{nullptr} if it fails
\end{codeblock}
\end{example}

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
\end{itemdescr}

\indexlibrarymember{delete}{operator}%
\begin{itemdecl}
void operator delete(void* ptr) noexcept;
void operator delete(void* ptr, std::size_t size) noexcept;
void operator delete(void* ptr, std::align_val_t alignment) noexcept;
void operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ptr} is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
\tcode{operator new(std::size_t)}
or
\tcode{operator new(std::size_t, std::align_val_t)}
which has not been invalidated by an intervening call to
\tcode{operator delete}.

\pnum
If the \tcode{alignment} parameter is not present,
\tcode{ptr} was returned by an allocation function
without an \tcode{alignment} parameter.
If present, the \tcode{alignment} argument
is equal to the \tcode{alignment} argument
passed to the allocation function that returned \tcode{ptr}.
If present, the \tcode{size} argument
is equal to the \tcode{size} argument
passed to the allocation function that returned \tcode{ptr}.

\pnum
\effects
The
deallocation functions\iref{basic.stc.dynamic.deallocation}
called by a
\grammarterm{delete-expression}\iref{expr.delete}
to render the value of \tcode{ptr} invalid.

\pnum
\required
A call to an \tcode{operator delete}
with a \tcode{size} parameter
may be changed to
a call to the corresponding \tcode{operator delete}
without a \tcode{size} parameter,
without affecting memory allocation.
\begin{note}
A conforming implementation is for
\tcode{operator delete(void* ptr, std::size_t size)} to simply call
\tcode{operator delete(ptr)}.
\end{note}

\pnum
\default
The functions that have a \tcode{size} parameter
forward their other parameters
to the corresponding function without a \tcode{size} parameter.
\begin{note}
See the note in the below \remarks paragraph.
\end{note}

\pnum
\default
If \tcode{ptr} is null, does nothing. Otherwise, reclaims the
storage allocated by the earlier call to \tcode{operator new}.

\pnum
\remarks
It is unspecified under what conditions part or all of such
\indextext{unspecified}%
reclaimed storage will be allocated by subsequent
calls to
\tcode{operator new}
or any of
\tcode{aligned_alloc},
\tcode{calloc},
\tcode{malloc},
or
\tcode{realloc},
declared in \libheaderref{cstdlib}.
This function is replaceable\iref{term.replaceable.function}.
If a replacement function
without a \tcode{size} parameter
is defined by the program,
the program should also define the corresponding
function with a \tcode{size} parameter.
If a replacement function
with a \tcode{size} parameter
is defined by the program,
the program shall also define the corresponding
version without the \tcode{size} parameter.
\begin{note}
The default behavior above might change in the future,
which will require replacing both deallocation functions
when replacing the allocation function.
\end{note}
\end{itemdescr}

\indexlibrarymember{delete}{operator}%
\begin{itemdecl}
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ptr} is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
\tcode{operator new(std::size_t)}
or
\tcode{operator new(std::size_t, std::align_val_t)}
which has not been invalidated by an intervening call to
\tcode{operator delete}.

\pnum
If the \tcode{alignment} parameter is not present,
\tcode{ptr} was returned by an allocation function
without an \tcode{alignment} parameter.
If present, the \tcode{alignment} argument
is equal to the \tcode{alignment} argument
passed to the allocation function that returned \tcode{ptr}.

\pnum
\effects
The
deallocation functions\iref{basic.stc.dynamic.deallocation}
called by the implementation
to render the value of \tcode{ptr} invalid
when the constructor invoked from a nothrow
placement version of the \grammarterm{new-expression} throws an exception.

\pnum
\default
Calls \tcode{operator delete(ptr)},
or \tcode{operator delete(ptr, alignment)},
respectively.

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
\end{itemdescr}

\rSec3[new.delete.array]{Array forms}

\indexlibrarymember{new}{operator}%
\begin{itemdecl}
void* operator new[](std::size_t size);
void* operator new[](std::size_t size, std::align_val_t alignment);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The
allocation functions\iref{basic.stc.dynamic.allocation}
called by the array form of a
\grammarterm{new-expression}\iref{expr.new}
to allocate
\tcode{size} bytes of storage.
The second form is called for a type with new-extended alignment, and
the first form is called otherwise.
\begin{footnote}
It is not the direct responsibility of
\tcode{operator new[]}
or
\tcode{operator delete[]}
to note the repetition count or element size of the array.
Those operations are performed elsewhere in the array
\keyword{new}
and
\keyword{delete}
expressions.
The array
\keyword{new}
expression, can, however, increase the \tcode{size} argument to
\tcode{operator new[]}
to obtain space to store supplemental information.
\end{footnote}

\pnum
\required
Same as for
the corresponding single-object forms.
This requirement is binding on any replacement versions of these functions.

\pnum
\default
Returns
\tcode{operator new(size)},
or
\tcode{operator new(size, alignment)},
respectively.

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
\end{itemdescr}

\indexlibrarymember{new}{operator}%
\begin{itemdecl}
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Same as above, except that these are called by a placement version of a
\grammarterm{new-expression}
when a \Cpp{} program prefers a null pointer result as an error indication,
instead of a
\tcode{bad_alloc}
exception.

\pnum
\required
Return a non-null pointer to suitably aligned storage\iref{basic.stc.dynamic},
or else return a null pointer.
Each of these nothrow versions of
\tcode{operator new[]}
returns a pointer obtained as if
acquired from the (possibly replaced)
corresponding non-placement function.
This requirement is binding on any replacement versions of these functions.

\pnum
\default
Calls \tcode{operator new[](size)},
or \tcode{operator new[](size, alignment)},
respectively.
If the call returns normally,
returns the result of that call.
Otherwise, returns a null pointer.

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
\end{itemdescr}

\indexlibrarymember{delete}{operator}%
\begin{itemdecl}
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment) noexcept;
void operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ptr} is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
\tcode{operator new[](std::size_t)}
or
\tcode{operator new[](std::size_t, std::align_val_t)}
which has not been invalidated by an intervening call to
\tcode{operator delete[]}.

\pnum
If the \tcode{alignment} parameter is not present,
\tcode{ptr} was returned by an allocation function
without an \tcode{alignment} parameter.
If present, the \tcode{alignment} argument
is equal to the \tcode{alignment} argument
passed to the allocation function that returned \tcode{ptr}.
If present, the \tcode{size} argument
is equal to the \tcode{size} argument
passed to the allocation function that returned \tcode{ptr}.

\pnum
\effects
The
deallocation functions\iref{basic.stc.dynamic.deallocation}
called by the array form of a
\grammarterm{delete-expression}
to render the value of \tcode{ptr} invalid.

\pnum
\required
A call to an \tcode{operator delete[]}
with a \tcode{size} parameter
may be changed to
a call to the corresponding \tcode{operator delete[]}
without a \tcode{size} parameter,
without affecting memory allocation.
\begin{note}
A conforming implementation is for
\tcode{operator delete[](void* ptr, std::size_t size)} to simply call
\tcode{operator delete[](ptr)}.
\end{note}

\pnum
\default
The functions that have a \tcode{size} parameter
forward their other parameters
to the corresponding function without a \tcode{size} parameter.
The functions that do not have a \tcode{size} parameter
forward their parameters
to the corresponding \tcode{operator delete} (single-object) function.

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
If a replacement function
without a \tcode{size} parameter
is defined by the program,
the program should also define the corresponding
function with a \tcode{size} parameter.
If a replacement function
with a \tcode{size} parameter
is defined by the program,
the program shall also define the corresponding
version without the \tcode{size} parameter.
\begin{note}
The default behavior above might change in the future,
which will require replacing both deallocation functions
when replacing the allocation function.
\end{note}
\end{itemdescr}

\indexlibrarymember{delete}{operator}%
\begin{itemdecl}
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{ptr} is a null pointer or
its value represents the address of
a block of memory allocated by
an earlier call to a (possibly replaced)
\tcode{operator new[](std::size_t)}
or
\tcode{operator new[](std::size_t, std::align_val_t)}
which has not been invalidated by an intervening call to
\tcode{operator delete[]}.

\pnum
If the \tcode{alignment} parameter is not present,
\tcode{ptr} was returned by an allocation function
without an \tcode{alignment} parameter.
If present, the \tcode{alignment} argument
is equal to the \tcode{alignment} argument
passed to the allocation function that returned \tcode{ptr}.

\pnum
\effects
The
deallocation functions\iref{basic.stc.dynamic.deallocation}
called by the implementation
to render the value of \tcode{ptr} invalid
when the constructor invoked from a nothrow
placement version of the array \grammarterm{new-expression} throws an exception.

\pnum
\default
Calls \tcode{operator delete[](ptr)},
or \tcode{operator delete[](ptr, alignment)},
respectively.

\pnum
\remarks
This function is replaceable\iref{term.replaceable.function}.
\end{itemdescr}

\rSec3[new.delete.placement]{Non-allocating forms}

\pnum
These functions are reserved; a \Cpp{} program may not define functions that displace
the versions in the \Cpp{} standard library\iref{constraints}.
The provisions of~\ref{basic.stc.dynamic} do not apply to these reserved
placement forms of \tcode{operator new} and \tcode{operator delete}.

\indexlibrarymember{new}{operator}%
\begin{itemdecl}
constexpr void* operator new(std::size_t size, void* ptr) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ptr}.

\pnum
\remarks
Intentionally performs no other action.

\pnum
\begin{example}
This can be useful for constructing an object at a known address:

\begin{codeblock}
void* place = operator new(sizeof(Something));
Something* p = new (place) Something();
\end{codeblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{new}{operator}%
\begin{itemdecl}
constexpr void* operator new[](std::size_t size, void* ptr) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ptr}.

\pnum
\remarks
Intentionally performs no other action.
\end{itemdescr}

\indexlibrarymember{delete}{operator}%
\begin{itemdecl}
void operator delete(void* ptr, void*) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Intentionally performs no action.

\pnum
\remarks
Default function called when any part of the initialization in a
placement \grammarterm{new-expression} that invokes the library's
non-array placement operator new
terminates by throwing an exception\iref{expr.new}.
\end{itemdescr}

\indexlibrarymember{delete}{operator}%
\begin{itemdecl}
void operator delete[](void* ptr, void*) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Intentionally performs no action.

\pnum
\remarks
Default function called when any part of the initialization in a
placement \grammarterm{new-expression} that invokes the library's
array placement operator new
terminates by throwing an exception\iref{expr.new}.
\end{itemdescr}

\rSec3[new.delete.dataraces]{Data races}

\pnum
For purposes of determining the existence of data races, the library versions
of \tcode{operator new}, user replacement versions of global \tcode{operator new},
the C standard library functions
\tcode{aligned_alloc}, \tcode{calloc}, and \tcode{malloc},
the library
versions of \tcode{operator delete}, user replacement
versions of \tcode{operator delete}, the C standard library function
\tcode{free}, and the C standard library function \tcode{realloc} shall not
introduce a data race\iref{res.on.data.races}.
Calls to these functions that allocate or deallocate a particular unit
of storage shall occur in a single total order, and each such deallocation call
shall happen before\iref{intro.multithread} the next allocation (if any) in
this order.

\rSec2[alloc.errors]{Storage allocation errors}

\rSec3[bad.alloc]{Class \tcode{bad_alloc}}%
\indexlibraryglobal{bad_alloc}%

\indexlibraryctor{bad_alloc}%
\begin{codeblock}
namespace std {
  class bad_alloc : public exception {
  public:
    // see \ref{exception} for the specification of the special member functions
    constexpr const char* what() const noexcept override;
  };
}
\end{codeblock}

\pnum
The class
\tcode{bad_alloc}
defines the type of objects thrown as
exceptions by the implementation to report a failure to allocate storage.

\indexlibrarymember{what}{bad_alloc}%
\begin{itemdecl}
constexpr const char* what() const noexcept override;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{bad_alloc::what}} \ntbs{}.
\end{itemdescr}

\rSec3[new.badlength]{Class \tcode{bad_array_new_length}}%
\indexlibraryglobal{bad_array_new_length}%
\indexlibraryctor{bad_array_new_length}%

\begin{codeblock}
namespace std {
  class bad_array_new_length : public bad_alloc {
  public:
    // see \ref{exception} for the specification of the special member functions
    constexpr const char* what() const noexcept override;
  };
}
\end{codeblock}

\pnum
The class \tcode{bad_array_new_length} defines the type of objects thrown as
exceptions by the implementation to report an attempt to allocate an array of size
less than zero or
greater than an \impldef{maximum size of an allocated object} limit\iref{expr.new}.

\indexlibrarymember{what}{bad_array_new_length}%
\begin{itemdecl}
constexpr const char* what() const noexcept override;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{bad_array_new_length::what}} \ntbs{}.
\end{itemdescr}

\rSec3[new.handler]{Type \tcode{new_handler}}

\indexlibraryglobal{new_handler}%
\begin{itemdecl}
using new_handler = void (*)();
\end{itemdecl}

\begin{itemdescr}
\pnum
The type of a
\term{handler function}
to be called by
\tcode{operator new()}
or
\tcode{operator new[]()}\iref{new.delete} when they cannot satisfy a request for additional storage.

\pnum
\required
A \tcode{new_handler} shall perform one of the following:
\begin{itemize}
\item
make more storage available for allocation and then return;
\item
throw an exception of type
\tcode{bad_alloc}
or a class derived from
\indexlibraryglobal{bad_alloc}%
\tcode{bad_alloc};
\item
terminate execution of the program without returning to the caller.
\indexlibraryglobal{abort}%
\indexlibraryglobal{exit}%
\end{itemize}
\end{itemdescr}

\rSec3[set.new.handler]{\tcode{set_new_handler}}

\indexlibraryglobal{set_new_handler}%
\begin{itemdecl}
new_handler set_new_handler(new_handler new_p) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Establishes the function designated by \tcode{new_p} as the current
\tcode{new_handler}.

\pnum
\returns
The previous \tcode{new_handler}.

\pnum
\remarks
The initial \tcode{new_handler} is a null pointer.
\end{itemdescr}

\rSec3[get.new.handler]{\tcode{get_new_handler}}

\indexlibraryglobal{get_new_handler}%
\begin{itemdecl}
new_handler get_new_handler() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The current \tcode{new_handler}.
\begin{note}
This can be a null pointer value.
\end{note}
\end{itemdescr}

\rSec2[ptr.launder]{Pointer optimization barrier}

\indexlibraryglobal{launder}%
\begin{itemdecl}
template<class T> constexpr T* launder(T* p) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{!is_function_v<T> \&\& !is_void_v<T>} is \tcode{true}.

\pnum
\expects
\tcode{p} represents the address \placeholder{A} of a byte in memory.
An object \placeholder{X} that is within its lifetime\iref{basic.life}
and whose type is similar\iref{conv.qual} to \tcode{T}
is located at the address \placeholder{A}.
All bytes of storage that would be
reachable through\iref{basic.compound} the result
are reachable through \tcode{p}.

\pnum
\returns
A value of type \tcode{T*} that points to \placeholder{X}.

\pnum
\remarks
An invocation of this function
may be used in a core constant expression
if and only if the (converted) value of its argument
may be used in place of the function invocation.

\pnum
\begin{note}
If a new object is created
in storage occupied by an existing object of the same type,
a pointer to the original object
can be used to refer to the new object
unless its complete object is a const object or it is a base class subobject;
in the latter cases,
this function can be used to obtain a usable pointer to the new object.
See~\ref{basic.life}.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
struct X { int n; };
const X *p = new const X{3};
const int a = p->n;
new (const_cast<X*>(p)) const X{5}; // \tcode{p} does not point to new object\iref{basic.life} because its type is \keyword{const}
const int b = p->n;                 // undefined behavior
const int c = std::launder(p)->n;   // OK
\end{codeblock}
\end{example}
\end{itemdescr}

\rSec2[hardware.interference]{Hardware interference size}

\indexlibraryglobal{hardware_destructive_interference_size}%
\begin{itemdecl}
inline constexpr size_t hardware_destructive_interference_size = @\impdef{}@;
\end{itemdecl}

\pnum
This number is the minimum recommended offset
between two concurrently-accessed objects
to avoid additional performance degradation due to contention
introduced by the implementation.
It shall be at least \tcode{alignof(max_align_t)}.

\indextext{cats!interfering with canines}%
\begin{example}
\begin{codeblock}
struct keep_apart {
  alignas(hardware_destructive_interference_size) atomic<int> cat;
  alignas(hardware_destructive_interference_size) atomic<int> dog;
};
\end{codeblock}
\end{example}

\indexlibraryglobal{hardware_constructive_interference_size}%
\begin{itemdecl}
inline constexpr size_t hardware_constructive_interference_size = @\impdef{}@;
\end{itemdecl}

\pnum
This number is the maximum recommended size of contiguous memory
occupied by two objects accessed with temporal locality by concurrent threads.
It shall be at least \tcode{alignof(max_align_t)}.

\indextext{dogs!obliviousness to interference}%
\begin{example}
\begin{codeblock}
struct together {
  atomic<int> dog;
  int puppy;
};
struct kennel {
  // Other data members...
  alignas(sizeof(together)) together pack;
  // Other data members...
};
static_assert(sizeof(together) <= hardware_constructive_interference_size);
\end{codeblock}
\end{example}

\rSec1[support.rtti]{Type identification}

\rSec2[support.rtti.general]{General}

\pnum
The header \libheaderref{typeinfo} defines a
type associated with type information generated by the implementation.
It also defines two types for reporting dynamic type identification errors.
The header \libheaderrefx{typeindex}{type.index.synopsis} defines
a wrapper type for use as an index type in associative containers\iref{associative}
and in unordered associative containers\iref{unord}.

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

\indexheader{typeinfo}%
\indexlibraryglobal{type_info}%
\indexlibraryglobal{bad_cast}%
\indexlibraryglobal{bad_typeid}%
\begin{codeblock}
// all freestanding
namespace std {
  class type_info;
  class bad_cast;
  class bad_typeid;
}
\end{codeblock}

\rSec2[type.info]{Class \tcode{type_info}}

\indexlibraryglobal{type_info}%
\begin{codeblock}
namespace std {
  class type_info {
  public:
    virtual ~type_info();
    constexpr bool operator==(const type_info& rhs) const noexcept;
    bool before(const type_info& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;

    type_info(const type_info&) = delete;
    type_info& operator=(const type_info&) = delete;
  };
}
\end{codeblock}

\pnum
The class
\tcode{type_info}
describes type information generated by the implementation\iref{expr.typeid}.
Objects of this class effectively store a pointer to a name for the type, and
an encoded value suitable for comparing two types for equality or collating order.
The names, encoding rule, and collating sequence for types are all unspecified
\indextext{unspecified}%
and may differ between programs.

\indexlibrarymember{operator==}{type_info}%
\begin{itemdecl}
constexpr bool operator==(const type_info& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Compares the current object with \tcode{rhs}.

\pnum
\returns
\tcode{true}
if the two values describe the same type.
\end{itemdescr}

\indexlibrarymember{before}{type_info}%
\begin{itemdecl}
bool before(const type_info& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Compares the current object with \tcode{rhs}.

\pnum
\returns
\tcode{true}
if
\tcode{*this}
precedes \tcode{rhs} in the implementation's collation order.
\end{itemdescr}

\indexlibrarymember{hash_code}{type_info}%
\begin{itemdecl}
size_t hash_code() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An unspecified value, except that within a single execution of the
program, it shall return the same value for any two \tcode{type_info}
objects which compare equal.

\pnum
\remarks
An implementation should return different values for two
\tcode{type_info} objects which do not compare equal.
\end{itemdescr}


\indexlibrarymember{name}{type_info}%
\begin{itemdecl}
const char* name() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{type_info::name()}} \ntbs{}.

\pnum
\remarks
The message may be a null-terminated multibyte string\iref{multibyte.strings},
suitable for conversion and display as a
\tcode{wstring}\iref{string.classes,locale.codecvt}.
\end{itemdescr}

\rSec2[bad.cast]{Class \tcode{bad_cast}}

\indexlibraryglobal{bad_cast}%
\indexlibraryctor{bad_cast}%
\begin{codeblock}
namespace std {
  class bad_cast : public exception {
  public:
    // see \ref{exception} for the specification of the special member functions
    constexpr const char* what() const noexcept override;
  };
}
\end{codeblock}

\pnum
The class
\tcode{bad_cast}
defines the type of objects thrown
as exceptions by the implementation to report the execution of an invalid
\indextext{cast!dynamic}%
\keyword{dynamic_cast}
expression\iref{expr.dynamic.cast}.

\indexlibrarymember{what}{bad_cast}%
\begin{itemdecl}
constexpr const char* what() const noexcept override;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{bad_cast::what}} \ntbs{}.
\end{itemdescr}

\rSec2[bad.typeid]{Class \tcode{bad_typeid}}

\indexlibraryglobal{bad_typeid}%
\indexlibraryctor{bad_typeid}%
\begin{codeblock}
namespace std {
  class bad_typeid : public exception {
  public:
    // see \ref{exception} for the specification of the special member functions
    constexpr const char* what() const noexcept override;
  };
}
\end{codeblock}

\pnum
The class
\tcode{bad_typeid}
defines the type of objects
thrown as exceptions by the implementation to report a null pointer
in a
\tcode{typeid}
expression\iref{expr.typeid}.

\indexlibrarymember{what}{bad_typeid}%
\begin{itemdecl}
constexpr const char* what() const noexcept override;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{bad_typeid::what}} \ntbs{}.
\end{itemdescr}

\rSec2[type.index.synopsis]{Header \tcode{<typeindex>} synopsis}

\indexheader{typeindex}%
\begin{codeblock}
#include <compare>              // see \ref{compare.syn}
#include <typeinfo>             // see \ref{typeinfo.syn}

namespace std {
  class type_index;
  template<class T> struct hash;
  template<> struct hash<type_index>;
}
\end{codeblock}

\rSec2[type.index]{Class \tcode{type_index}}

\indexlibraryglobal{type_index}%
\begin{codeblock}
namespace std {
  class type_index {
  public:
    type_index(const type_info& rhs) noexcept;
    bool operator==(const type_index& rhs) const noexcept;
    bool operator< (const type_index& rhs) const noexcept;
    bool operator> (const type_index& rhs) const noexcept;
    bool operator<=(const type_index& rhs) const noexcept;
    bool operator>=(const type_index& rhs) const noexcept;
    strong_ordering operator<=>(const type_index& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;

  private:
    const type_info* target;    // \expos
    // Note that the use of a pointer here, rather than a reference,
    // means that the default copy/move constructor and assignment
    // operators will be provided and work as expected.
  };
}
\end{codeblock}

\pnum
The class \tcode{type_index} provides a simple wrapper for
\tcode{type_info} which can be used as an index type in associative
containers\iref{associative} and in unordered associative
containers\iref{unord}.

\indexlibraryctor{type_index}%
\begin{itemdecl}
type_index(const type_info& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a \tcode{type_index} object, the equivalent of \tcode{target = \&rhs}.
\end{itemdescr}

\indexlibrarymember{operator==}{type_index}%
\begin{itemdecl}
bool operator==(const type_index& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{*target == *rhs.target}.
\end{itemdescr}

\indexlibrarymember{operator<}{type_index}%
\begin{itemdecl}
bool operator<(const type_index& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{target->before(*rhs.target)}.
\end{itemdescr}

\indexlibrarymember{operator>}{type_index}%
\begin{itemdecl}
bool operator>(const type_index& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{rhs.target->before(*target)}.
\end{itemdescr}

\indexlibrarymember{operator<=}{type_index}%
\begin{itemdecl}
bool operator<=(const type_index& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!rhs.target->before(*target)}.
\end{itemdescr}

\indexlibrarymember{operator>=}{type_index}%
\begin{itemdecl}
bool operator>=(const type_index& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!target->before(*rhs.target)}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{type_index}%
\begin{itemdecl}
strong_ordering operator<=>(const type_index& rhs) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
if (*target == *rhs.target) return strong_ordering::equal;
if (target->before(*rhs.target)) return strong_ordering::less;
return strong_ordering::greater;
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{hash_code}{type_index}%
\begin{itemdecl}
size_t hash_code() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{target->hash_code()}.
\end{itemdescr}

\indexlibrarymember{name}{type_index}%
\begin{itemdecl}
const char* name() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{target->name()}.
\end{itemdescr}

\indexlibrarymember{hash}{type_index}%
\begin{itemdecl}
template<> struct hash<type_index>;
\end{itemdecl}

\begin{itemdescr}
\pnum
For an object \tcode{index} of type \tcode{type_index},
\tcode{hash<type_index>()(index)} shall evaluate to the same result as \tcode{index.hash_code()}.
\end{itemdescr}

\rSec1[support.srcloc]{Source location}

\rSec2[source.location.syn]{Header \tcode{<source_location>} synopsis}

\pnum
The header \libheaderdef{source_location} defines
the class \tcode{source_location}
that provides a means to obtain source location information.

\begin{codeblock}
// all freestanding
namespace std {
  struct source_location;
}
\end{codeblock}

\rSec2[support.srcloc.class]{Class \tcode{source_location}}

\rSec3[support.srcloc.class.general]{General}

\indexlibraryglobal{source_location}%
\begin{codeblock}
namespace std {
  struct source_location {
    // source location construction
    static consteval source_location current() noexcept;
    constexpr source_location() noexcept;

    // source location field access
    constexpr uint_least32_t line() const noexcept;
    constexpr uint_least32_t column() const noexcept;
    constexpr const char* file_name() const noexcept;
    constexpr const char* function_name() const noexcept;

  private:
    uint_least32_t line_;               // \expos
    uint_least32_t column_;             // \expos
    const char* file_name_;             // \expos
    const char* function_name_;         // \expos
  };
}
\end{codeblock}

\pnum
The type \tcode{source_location} meets the
\oldconcept{DefaultConstructible},
\oldconcept{CopyConstructible},
\oldconcept{Copy\-Assignable},
\oldconcept{Swappable}, and
\oldconcept{Destructible}
requirements\iref{utility.arg.requirements,swappable.requirements}.
All of the following conditions are \tcode{true}:
\begin{itemize}
\item \tcode{is_nothrow_move_constructible_v<source_location>}
\item \tcode{is_nothrow_move_assignable_v<source_location>}
\item \tcode{is_nothrow_swappable_v<source_location>}
\end{itemize}
\begin{note}
The intent of \tcode{source_location} is
to have a small size and efficient copying.
It is unspecified
whether the copy/move constructors and the copy/move assignment operators
are trivial and/or constexpr.
\end{note}

\pnum
The data members \tcode{file_name_} and \tcode{function_name_}
always each refer to an \ntbs{}.

\pnum
The copy/move constructors and the copy/move assignment operators of
\tcode{source_location} meet the following postconditions:
Given two objects  \tcode{lhs} and \tcode{rhs} of type \tcode{source_location},
where \tcode{lhs} is a copy/move result of \tcode{rhs}, and
where \tcode{rhs_p} is a value denoting the state of \tcode{rhs}
before the corresponding copy/move operation,
then each of the following conditions is \tcode{true}:
\begin{itemize}
\item \tcode{strcmp(lhs.file_name(), rhs_p.file_name()) == 0}
\item \tcode{strcmp(lhs.function_name(), rhs_p.function_name()) == 0}
\item \tcode{lhs.line() == rhs_p.line()}
\item \tcode{lhs.column() == rhs_p.column()}
\end{itemize}

\rSec3[support.srcloc.cons]{Creation}

\begin{itemdecl}
static consteval source_location current() noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\begin{itemize}
\item
  When invoked by a function call
  whose \grammarterm{postfix-expression} is
  a (possibly parenthesized) \grammarterm{id-expression} naming \tcode{current},
  returns a \tcode{source_location} with an \impldef{return value of \tcode{source_location::current}} value.
  The value should be affected by \tcode{\#line}\iref{cpp.line}
  in the same manner as for \mname{LINE} and \mname{FILE}.
  The values of the exposition-only data members
  of the returned \tcode{source_location} object
  are indicated in \tref{support.srcloc.current}.

\begin{libefftabvalue}
  {Value of object returned by \tcode{current}}
  {support.srcloc.current}
\tcode{line_}    &
  A presumed line number\iref{cpp.predefined}.
  Line numbers are presumed to be 1-indexed;
  however, an implementation is encouraged to use 0
  when the line number is unknown. \\ \rowsep
\tcode{column_}  &
  An \impldef{column value of \tcode{source_location::current}} value denoting
  some offset from the start of the line denoted by \tcode{line_}.
  Column numbers are presumed to be 1-indexed;
  however, an implementation is encouraged to use 0
  when the column number is unknown. \\ \rowsep
\tcode{file_name_} &
  A presumed name of the current source file\iref{cpp.predefined} as an \ntbs{}.
  \\ \rowsep
\tcode{function_name_} &
  A name of the current function
  such as in \mname{func}\iref{dcl.fct.def.general} if any,
  an empty string otherwise. \\
\end{libefftabvalue}

\item
  Otherwise, when invoked in some other way, returns a
  \tcode{source_location} whose data members are initialized
  with valid but unspecified values.
\end{itemize}

\pnum
\remarks
Any call to \tcode{current} that appears
as a default member initializer\iref{class.mem.general}, or
as a subexpression thereof,
should correspond to the location of
the constructor definition or aggregate initialization
that uses the default member initializer.
Any call to \tcode{current} that appears
as a default argument\iref{dcl.fct.default}, or
as a subexpression thereof,
should correspond to the location of the invocation of the function
that uses the default argument\iref{expr.call}.
\end{itemdescr}

\pnum
\begin{example}
\begin{codeblock}
struct s {
  source_location member = source_location::current();
  int other_member;
  s(source_location loc = source_location::current())
    : member(loc)               // values of \tcode{member} refer to the location of the calling function\iref{dcl.fct.default}
  {}
  s(int blather) :              // values of \tcode{member} refer to this location
    other_member(blather)
  {}
  s(double)                     // values of \tcode{member} refer to this location
  {}
};
void f(source_location a = source_location::current()) {
  source_location b = source_location::current();       // values in \tcode{b} refer to this line
}

void g() {
  f();                          // \tcode{f}'s first argument corresponds to this line of code

  source_location c = source_location::current();
  f(c);                         // \tcode{f}'s first argument gets the same values as \tcode{c}, above
}
\end{codeblock}
\end{example}

\begin{itemdecl}
constexpr source_location() noexcept;
\end{itemdecl}
\begin{itemdescr}

\pnum
\effects
The data members are initialized with valid but unspecified values.
\end{itemdescr}

\rSec3[support.srcloc.obs]{Observers}

\begin{itemdecl}
constexpr uint_least32_t line() const noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\tcode{line_}.
\end{itemdescr}

\begin{itemdecl}
constexpr uint_least32_t column() const noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\tcode{column_}.
\end{itemdescr}

\begin{itemdecl}
constexpr const char* file_name() const noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\tcode{file_name_}.
\end{itemdescr}

\begin{itemdecl}
constexpr const char* function_name() const noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\tcode{function_name_}.
\end{itemdescr}

\rSec1[support.exception]{Exception handling}

\rSec2[support.exception.general]{General}

\pnum
The header \libheaderdef{exception}
defines several types and functions related to the handling of exceptions in a \Cpp{} program.

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

\begin{codeblock}
// all freestanding
namespace std {
  class exception;
  class bad_exception;
  class nested_exception;

  using terminate_handler = void (*)();
  terminate_handler get_terminate() noexcept;
  terminate_handler set_terminate(terminate_handler f) noexcept;
  [[noreturn]] void terminate() noexcept;

  constexpr int uncaught_exceptions() noexcept;

  using exception_ptr = @\unspec@;

  constexpr exception_ptr current_exception() noexcept;
  [[noreturn]] constexpr void rethrow_exception(exception_ptr p);
  template<class E> constexpr exception_ptr make_exception_ptr(E e) noexcept;
  template<class E> constexpr const E* exception_ptr_cast(const exception_ptr& p) noexcept;
  template<class E> void exception_ptr_cast(const exception_ptr&&) = delete;

  template<class T> [[noreturn]] constexpr void throw_with_nested(T&& t);
  template<class E> constexpr void rethrow_if_nested(const E& e);
}
\end{codeblock}

\rSec2[exception]{Class \tcode{exception}}

\indexlibraryglobal{exception}%
\indexlibraryctor{exception}%
\begin{codeblock}
namespace std {
  class exception {
  public:
    constexpr exception() noexcept;
    constexpr exception(const exception&) noexcept;
    constexpr exception& operator=(const exception&) noexcept;
    constexpr virtual ~exception();
    constexpr virtual const char* what() const noexcept;
  };
}
\end{codeblock}

\pnum
The class
\tcode{exception}
defines the base
class for the types of objects thrown as exceptions by
\Cpp{} standard library components, and certain
expressions, to report errors detected during program execution.

\pnum
Except where explicitly specified otherwise,
each standard library class \tcode{T} that derives from class \tcode{exception}
has the following publicly accessible member functions, each of them having
a non-throwing exception specification\iref{except.spec}:
\begin{itemize}
\item default constructor (unless the class synopsis shows other constructors)
\item copy constructor
\item copy assignment operator
\end{itemize}
The copy constructor and the copy assignment operator meet
the following postcondition: If two objects \tcode{lhs} and \tcode{rhs} both have
dynamic type \tcode{T} and \tcode{lhs} is a copy of \tcode{rhs}, then
\tcode{strcmp(lhs.what(), rhs.what())} is equal to \tcode{0}.
The \tcode{what()} member function of each such \tcode{T} satisfies the
constraints specified for \tcode{exception::what()} (see below).

\indexlibraryctor{exception}%
\indexlibrarymember{operator=}{exception}%
\begin{itemdecl}
constexpr exception(const exception& rhs) noexcept;
constexpr exception& operator=(const exception& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
If \tcode{*this} and \tcode{rhs} both have dynamic type \tcode{exception}
then the value of the expression \tcode{strcmp(what(), rhs.what())} shall equal 0.
\end{itemdescr}

\indexlibrarydtor{exception}%
\begin{itemdecl}
constexpr virtual ~exception();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Destroys an object of class
\tcode{exception}.
\end{itemdescr}

\indexlibrarymember{what}{exception}%
\begin{itemdecl}
constexpr virtual const char* what() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{exception::what}} \ntbs{},
which during constant evaluation is encoded with
the ordinary literal encoding\iref{lex.ccon}.

\pnum
\remarks
The message may be a null-terminated multibyte string\iref{multibyte.strings},
suitable for conversion and display as a
\tcode{wstring}\iref{string.classes,locale.codecvt}.
The return value remains valid until the exception object from which
it is obtained is destroyed or a non-\keyword{const}
member function of the exception object is called.
\end{itemdescr}

\rSec2[bad.exception]{Class \tcode{bad_exception}}

\indexlibraryglobal{bad_exception}%
\indexlibraryctor{bad_exception}%
\begin{codeblock}
namespace std {
  class bad_exception : public exception {
  public:
    // see \ref{exception} for the specification of the special member functions
    constexpr const char* what() const noexcept override;
  };
}
\end{codeblock}

\pnum
The class
\tcode{bad_exception}
defines the type of the object
referenced by the \tcode{exception_ptr}
returned from a call to \tcode{current_exception}\iref{propagation}
when the currently active exception object fails to copy.

\indexlibrarymember{what}{bad_exception}%
\begin{itemdecl}
constexpr const char* what() const noexcept override;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \impldef{return value of \tcode{bad_exception::what}} \ntbs{}.
\end{itemdescr}

\rSec2[exception.terminate]{Abnormal termination}

\rSec3[terminate.handler]{Type \tcode{terminate_handler}}

\indexlibraryglobal{terminate_handler}%
\begin{itemdecl}
using terminate_handler = void (*)();
\end{itemdecl}

\begin{itemdescr}
\pnum
The type of a \term{handler function}
to be invoked by \tcode{terminate}
\indexlibraryglobal{terminate}%
when terminating exception processing.

\pnum
\required
A \tcode{terminate_handler} shall
terminate execution of the program without returning to the caller.

\pnum
\default
The implementation's default \tcode{terminate_handler} calls
\tcode{abort()}.%
\indexlibraryglobal{abort}%
\end{itemdescr}

\rSec3[set.terminate]{\tcode{set_terminate}}

\indexlibraryglobal{set_terminate}%
\begin{itemdecl}
terminate_handler set_terminate(terminate_handler f) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Establishes the function designated by \tcode{f} as the current
handler function for terminating exception processing.

\pnum
\returns
The previous \tcode{terminate_handler}.

\pnum
\remarks
It is unspecified whether a null pointer value designates the default
\tcode{terminate_handler}.
\end{itemdescr}

\rSec3[get.terminate]{\tcode{get_terminate}}

\indexlibraryglobal{get_terminate}%
\begin{itemdecl}
terminate_handler get_terminate() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The current \tcode{terminate_handler}.
\begin{note}
This can be a null pointer value.
\end{note}
\end{itemdescr}

\rSec3[terminate]{\tcode{terminate}}

\indexlibraryglobal{terminate}%
\begin{itemdecl}
[[noreturn]] void terminate() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls a \tcode{terminate_handler} function. It is unspecified which
\tcode{terminate_handler} function will be called if an exception is active
during a call to \tcode{set_terminate}.
Otherwise calls the current \tcode{terminate_handler} function.
\begin{note}
A
default \tcode{terminate_handler} is always considered a callable handler in
this context.
\end{note}

\pnum
\remarks
Called by the implementation when exception
handling must be abandoned for any of several reasons\iref{except.terminate}.
May also be called directly by the program.
\end{itemdescr}

\rSec2[uncaught.exceptions]{\tcode{uncaught_exceptions}}

\indexlibraryglobal{uncaught_exceptions}%
\begin{itemdecl}
constexpr int uncaught_exceptions() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The number of uncaught exceptions\iref{except.throw} in the current thread.

\pnum
\remarks
When \tcode{uncaught_exceptions() > 0},
throwing an exception can result in a call of the function
\tcode{std::terminate}\iref{except.terminate}.
\end{itemdescr}

\rSec2[propagation]{Exception propagation}

\indexlibraryglobal{exception_ptr}%
\begin{itemdecl}
using exception_ptr = @\unspec@;
\end{itemdecl}

\begin{itemdescr}
\pnum
The type \tcode{exception_ptr} can be used to refer to an exception object.

\pnum
\tcode{exception_ptr} meets the requirements of
\oldconcept{NullablePointer} (\tref{cpp17.nullablepointer}).

\pnum
Two non-null values of type \tcode{exception_ptr} are equivalent and compare equal if and
only if they refer to the same exception.

\pnum
The default constructor of \tcode{exception_ptr} produces the null value of the
type.

\pnum
\tcode{exception_ptr} shall not be implicitly convertible to any arithmetic,
enumeration, or pointer type.

\pnum
\begin{note}
An implementation can use a reference-counted smart
pointer as \tcode{exception_ptr}.
\end{note}

\pnum
For purposes of determining the presence of a data race, operations on
\tcode{exception_ptr} objects shall access and modify only the
\tcode{exception_ptr} objects themselves and not the exceptions they refer to.
Use of \tcode{rethrow_exception} or \tcode{exception_ptr_cast}
on \tcode{exception_ptr} objects that refer to
the same exception object shall not introduce a data race.
\begin{note}
If
\tcode{rethrow_exception} rethrows the same exception object (rather than a copy),
concurrent access to that rethrown exception object can introduce a data race.
Changes in the number of \tcode{exception_ptr} objects that refer to a
particular exception do not introduce a data race.
\end{note}

\pnum
All member functions are marked \tcode{constexpr}.
\end{itemdescr}

\indexlibraryglobal{current_exception}%
\begin{itemdecl}
constexpr exception_ptr current_exception() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \tcode{exception_ptr} object that refers to
the currently handled exception\iref{except.handle} or a copy of the currently
handled exception, or a null \tcode{exception_ptr} object if no exception is being
handled. The referenced object shall remain valid at least as long as there is an
\tcode{exception_ptr} object that refers to it.
If the function needs to allocate memory and the attempt fails, it returns an
\tcode{exception_ptr} object that refers to an instance of \tcode{bad_alloc}.
It is unspecified whether the return values of two successive calls to
\tcode{current_exception} refer to the same exception object.
\begin{note}
That is, it is unspecified whether \tcode{current_exception}
creates a new copy each time it is called.
\end{note}
If the attempt to copy the current exception object throws an exception, the function
returns an \tcode{exception_ptr} object that refers to the thrown exception or,
if this is not possible, to an instance of \tcode{bad_exception}.
\begin{note}
The copy constructor of the thrown exception can also fail,
so the implementation can substitute a \tcode{bad_exception} object
to avoid infinite recursion.
\end{note}
\end{itemdescr}

\indexlibraryglobal{rethrow_exception}%
\begin{itemdecl}
[[noreturn]] constexpr void rethrow_exception(exception_ptr p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not a null pointer.

\pnum
\effects
Let $u$ be the exception object to which \tcode{p} refers, or
a copy of that exception object.
It is unspecified whether a copy is made, and
memory for the copy is allocated in an unspecified way.
\begin{itemize}
\item
If allocating memory to form $u$ fails,
throws an instance of \tcode{bad_alloc};
\item
otherwise, if copying the exception to which \tcode{p} refers
to form $u$ throws an exception, throws that exception;
\item
otherwise, throws $u$.
\end{itemize}
\end{itemdescr}

\indexlibraryglobal{make_exception_ptr}%
\begin{itemdecl}
template<class E> constexpr exception_ptr make_exception_ptr(E e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Creates an \tcode{exception_ptr} object that refers to a copy of \tcode{e}, as if:
\begin{codeblock}
try {
  throw e;
} catch(...) {
  return current_exception();
}
\end{codeblock}

\pnum
\begin{note}
This function is provided for convenience and
efficiency reasons.
\end{note}
\end{itemdescr}

\indexlibraryglobal{exception_ptr_cast}%
\begin{itemdecl}
template<class E> constexpr const E* exception_ptr_cast(const exception_ptr& p) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{E} is a cv-unqualified complete object type.
\tcode{E} is not an array type.
\tcode{E} is not a pointer or pointer-to-member type.
\begin{note}
When \tcode{E} is a pointer or pointer-to-member type,
a handler of type \tcode{const E\&} can match
without binding to the exception object itself.
\end{note}

\pnum
\returns
A pointer to the exception object referred to by \tcode{p},
if \tcode{p} is not null and
a handler of type \tcode{const E\&}
would be a match\iref{except.handle} for that exception object.
Otherwise, \tcode{nullptr}.
\end{itemdescr}

\rSec2[except.nested]{\tcode{nested_exception}}

\indexlibraryglobal{nested_exception}%
\begin{codeblock}
namespace std {
  class nested_exception {
  public:
    constexpr nested_exception() noexcept;
    constexpr nested_exception(const nested_exception&) noexcept = default;
    constexpr nested_exception& operator=(const nested_exception&) noexcept = default;
    constexpr virtual ~nested_exception() = default;

    // access functions
    [[noreturn]] constexpr void rethrow_nested() const;
    constexpr exception_ptr nested_ptr() const noexcept;
  };

  template<class T> [[noreturn]] constexpr void throw_with_nested(T&& t);
  template<class E> constexpr void rethrow_if_nested(const E& e);
}
\end{codeblock}

\pnum
The class \tcode{nested_exception} is designed for use as a mixin through
multiple inheritance. It captures the currently handled exception and stores it
for later use.

\pnum
\begin{note}
\tcode{nested_exception} has a virtual destructor to make it a
polymorphic class. Its presence can be tested for with \keyword{dynamic_cast}.
\end{note}

\indexlibraryctor{nested_exception}%
\begin{itemdecl}
constexpr nested_exception() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The constructor calls \tcode{current_exception()} and stores the returned value.
\end{itemdescr}

\indexlibrarymember{rethrow_nested}{nested_exception}%
\begin{itemdecl}
[[noreturn]] constexpr void rethrow_nested() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{nested_ptr()} returns a null pointer, the function calls the function \tcode{std::terminate}.
Otherwise, it throws the stored exception captured by \tcode{*this}.
\end{itemdescr}

\indexlibrarymember{nested_ptr}{nested_exception}%
\begin{itemdecl}
constexpr exception_ptr nested_ptr() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The stored exception captured by this \tcode{nested_exception} object.
\end{itemdescr}

\indexlibrarymember{throw_with_nested}{nested_exception}%
\begin{itemdecl}
template<class T> [[noreturn]] constexpr void throw_with_nested(T&& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let \tcode{U} be \tcode{decay_t<T>}.

\pnum
\expects
\tcode{U} meets the \oldconcept{CopyConstructible} requirements.

\pnum
\throws
If \tcode{is_class_v<U> \&\& !is_final_v<U> \&\& !is_base_of_v<nested_exception, U>}
is \tcode{true},
an exception of unspecified type that is publicly derived from both
\tcode{U} and \tcode{nested_exception}
and constructed from \tcode{std::forward<T>(t)}, otherwise
\tcode{std::forward<T>(t)}.
\end{itemdescr}

\indexlibrarymember{rethrow_if_nested}{nested_exception}%
\begin{itemdecl}
template<class E> constexpr void rethrow_if_nested(const E& e);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{E} is not a polymorphic class type, or
if \tcode{nested_exception} is an inaccessible or ambiguous base class of \tcode{E},
there is no effect.
Otherwise, performs:
\begin{codeblock}
if (auto p = dynamic_cast<const nested_exception*>(addressof(e)))
  p->rethrow_nested();
\end{codeblock}
\end{itemdescr}

\rSec1[support.contract]{Contract-violation handling}

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

\pnum
The header \libheader{contracts} defines types
for reporting information about contract violations\iref{basic.contract.eval}.

\indexheader{contracts}
\indexlibraryglobal{contract_violation}%
\begin{codeblock}
// all freestanding
namespace std::contracts {

  enum class assertion_kind : @\unspec@ {
    pre = 1,
    post = 2,
    assert = 3
  };

  enum class evaluation_semantic : @\unspec@ {
    ignore = 1,
    observe = 2,
    enforce = 3,
    quick_enforce = 4
  };

  enum class detection_mode : @\unspec@ {
    predicate_false = 1,
    evaluation_exception = 2
  };

  class contract_violation {
    // no user-accessible constructor
  public:
    contract_violation(const contract_violation&) = delete;
    contract_violation& operator=(const contract_violation&) = delete;

    @\seebelow@ ~contract_violation();

    const char* comment() const noexcept;
    contracts::detection_mode detection_mode() const noexcept;
    bool is_terminating() const noexcept;
    assertion_kind kind() const noexcept;
    source_location location() const noexcept;
    evaluation_semantic semantic() const noexcept;
  };

  void invoke_default_contract_violation_handler(const contract_violation&);
}
\end{codeblock}

\rSec2[support.contract.enum]{Enumerations}

\pnum
\recommended
For all enumerations in \ref{support.contract.enum},
if implementation-defined enumerators are provided,
they should have a minimum value of $1000$.

\pnum
The enumerators of \tcode{assertion_kind}
correspond to
the syntactic forms of a contract assertion\iref{basic.contract.general},
with meanings listed in Table~\ref{tab:support.contract.enum.kind}.

\begin{floattable}{Enum \tcode{assertion_kind}}{support.contract.enum.kind}
{ll}
\topline
\lhdr{Name}    & \rhdr{Meaning}                        \\ \capsep
\tcode{pre}    & A precondition assertion              \\ \rowsep
\tcode{post}   & A postcondition assertion             \\ \rowsep
\tcode{assert} & An \grammarterm{assertion-statement}  \\ \rowsep
\end{floattable}

\pnum
The enumerators of \tcode{evaluation_semantic}
correspond to
the evaluation semantics with which
a contract assertion may be evaluated\iref{basic.contract.eval},
with meanings listed in Table~\ref{tab:support.contract.enum.semantic}.

\begin{floattable}{Enum \tcode{evaluation_semantic}}{support.contract.enum.semantic}
{ll}
\topline
\lhdr{Name}           & \rhdr{Meaning}                    \\ \capsep
\tcode{ignore}        & Ignore evaluation semantic        \\ \rowsep
\tcode{observe}       & Observe evaluation semantic       \\ \rowsep
\tcode{enforce}       & Enforce evaluation semantic       \\ \rowsep
\tcode{quick_enforce} & Quick-enforce evaluation semantic \\ \rowsep
\end{floattable}

\pnum
The enumerators of \tcode{detection_mode} correspond to the manners in which a
contract violation can be identified\iref{basic.contract.eval}, with
meanings listed in \mbox{Table~\ref{tab:support.contract.enum.detection}}.

\begin{floattable}{Enum \tcode{detection_mode}}{support.contract.enum.detection}
{lp{.6\hsize}}
\topline
\lhdr{Name}                  & \rhdr{Meaning}                    \\ \capsep
\tcode{predicate_false}      & The predicate of the contract assertion evaluated to \keyword{false} or would have evaluated to \keyword{false}. \\ \rowsep
\tcode{evaluation_exception} & An uncaught exception occurred during evaluation of the contract assertion. \\ \rowsep
\end{floattable}

\rSec2[support.contract.violation]{Class \tcode{contract_violation}}

\pnum
\indexlibraryglobal{contract_violation}%
The class \tcode{contract_violation}
defines the type of objects used to represent
a contract violation that has been detected
during the evaluation of a contract assertion
with a particular evaluation semantic\iref{basic.contract.eval}.
Objects of this type can
be created only by the implementation.
It is
\impldef{whether \tcode{contract_violation} has a virtual destructor}
whether the destructor is virtual.

\begin{itemdecl}
const char* comment() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An
\impldef{the contents provided in the \tcode{comment} field of \tcode{contract_violation}}
\ntmbs{} in
the ordinary literal encoding\iref{lex.charset}.

\pnum
\recommended
The string returned
should contain a textual representation
of the predicate of the violated contract assertion
or an empty string if
storing a textual representation is undesired.
\begin{note}
The string can represent a
truncated, reformatted, or summarized rendering of the
predicate, before or after preprocessing.
\end{note}

\end{itemdescr}

\begin{itemdecl}
contracts::detection_mode detection_mode() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The enumerator value
corresponding to
the manner in which the contract violation was identified.

\end{itemdescr}

\begin{itemdecl}
bool is_terminating() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\indextext{contract evaluation semantics!terminating}%
\pnum
\returns
\keyword{true} if the evaluation semantic is
a terminating semantic\iref{basic.contract.eval};
otherwise, \tcode{false}.

\end{itemdescr}

\begin{itemdecl}
assertion_kind kind() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The enumerator value
corresponding to
the syntactic form of the violated contract assertion.

\end{itemdescr}

\begin{itemdecl}
source_location location() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{source_location} object
with
\impldef{the contents provided in the \tcode{location} field of \tcode{contract_violation}}
value.

\pnum
\recommended
The value returned should be
a default constructed \tcode{source_location} object
or a value identifying the violated contract assertion:
\begin{itemize}
\item
When possible,
if the violated contract assertion was a precondition,
the source location of the function invocation should be returned.
\item
Otherwise,
the source location of the contract assertion should be returned.
\end{itemize}

\end{itemdescr}

\begin{itemdecl}
evaluation_semantic semantic() const noexcept;
\end{itemdecl}

\begin{itemdescr}

\pnum
\returns
The enumerator value
corresponding to
the evaluation semantic with which
the violated contract assertion was evaluated.

\end{itemdescr}

\rSec2[support.contract.invoke]{Invoke default handler}

\begin{itemdecl}
void invoke_default_contract_violation_handler(const contract_violation& v);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Invokes the default contract-violation handler\iref{basic.contract.handler}
with the argument \tcode{v}.

\end{itemdescr}

\rSec1[support.initlist]{Initializer lists}

\rSec2[support.initlist.general]{General}

\pnum
The header \libheaderdef{initializer_list} defines a class template and several
support functions related to list-initialization~(see \ref{dcl.init.list}).
\indextext{signal-safe!\idxcode{initializer_list} functions}%
All functions specified in \ref{support.initlist} are signal-safe\iref{support.signal}.

\rSec2[initializer.list.syn]{Header \tcode{<initializer_list>} synopsis}
\indexlibraryglobal{initializer_list}%
\indexlibraryglobal{begin}%
\indexlibraryglobal{end}%

\begin{codeblock}
// all freestanding
namespace std {
  template<class E> class initializer_list {
  public:
    using value_type      = E;
    using reference       = const E&;
    using const_reference = const E&;
    using size_type       = size_t;

    using iterator        = const E*;
    using const_iterator  = const E*;

    constexpr initializer_list() noexcept;

    constexpr const E* data() const noexcept;
    constexpr size_t size() const noexcept;
    constexpr bool empty() const noexcept;
    constexpr const E* begin() const noexcept;
    constexpr const E* end() const noexcept;
  };
}
\end{codeblock}

\pnum
An object of type \tcode{initializer_list<E>} provides access to an array of
objects of type \tcode{const E}.
\begin{note}
A pair of pointers or a pointer plus
a length would be obvious representations for \tcode{initializer_list}.
\tcode{initializer_list} is used to implement initializer lists as specified
in~\ref{dcl.init.list}. Copying an \tcode{initializer_list} does not copy the underlying
elements.
\end{note}

\pnum
If an explicit specialization or partial specialization of
\tcode{initializer_list} is declared, the program is ill-formed.

\rSec2[support.initlist.cons]{Initializer list constructors}

\indexlibraryctor{initializer_list}%
\begin{itemdecl}
constexpr initializer_list() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{size() == 0}.
\end{itemdescr}

\rSec2[support.initlist.access]{Initializer list access}

\indexlibrarymember{begin}{initializer_list}%
\begin{itemdecl}
constexpr const E* begin() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A pointer to the beginning of the array. If \tcode{size() == 0} the
values of \tcode{begin()} and \tcode{end()} are unspecified but they shall be
identical.
\end{itemdescr}

\indexlibrarymember{end}{initializer_list}%
\begin{itemdecl}
constexpr const E* end() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{begin() + size()}.
\end{itemdescr}

\indexlibrarymember{data}{initializer_list}%
\begin{itemdecl}
constexpr const E* data() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{begin()}.
\end{itemdescr}

\indexlibrarymember{size}{initializer_list}%
\begin{itemdecl}
constexpr size_t size() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The number of elements in the array.

\pnum
\complexity
Constant.
\end{itemdescr}

\indexlibrarymember{empty}{initializer_list}%
\begin{itemdecl}
constexpr bool empty() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{size() == 0}.
\end{itemdescr}

\rSec1[cmp]{Comparisons}

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

\pnum
The header \libheaderdef{compare} specifies types, objects, and functions
for use primarily in connection with
the three-way comparison operator\iref{expr.spaceship}.

\indexlibraryglobal{is_eq}%
\indexlibraryglobal{is_neq}%
\indexlibraryglobal{is_lt}%
\indexlibraryglobal{is_lteq}%
\indexlibraryglobal{is_gt}%
\indexlibraryglobal{is_geq}%
\indexlibraryglobal{is_gteq}%
\indexlibraryglobal{common_comparison_category_t}%
\indexlibraryglobal{type_order_v}%
\begin{codeblock}
// all freestanding
namespace std {
  // \ref{cmp.categories}, comparison category types
  class partial_ordering;
  class weak_ordering;
  class strong_ordering;

  // named comparison functions
  constexpr bool is_eq  (partial_ordering cmp) noexcept { return cmp == 0; }
  constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; }
  constexpr bool is_lt  (partial_ordering cmp) noexcept { return cmp < 0; }
  constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
  constexpr bool is_gt  (partial_ordering cmp) noexcept { return cmp > 0; }
  constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }

  // \ref{cmp.common}, common comparison category type
  template<class... Ts>
  struct common_comparison_category {
    using type = @\seebelow@;
  };
  template<class... Ts>
    using common_comparison_category_t = common_comparison_category<Ts...>::type;

  // \ref{cmp.concept}, concept \libconcept{three_way_comparable}
  template<class T, class Cat = partial_ordering>
    concept three_way_comparable = @\seebelow@;
  template<class T, class U, class Cat = partial_ordering>
    concept three_way_comparable_with = @\seebelow@;

  // \ref{cmp.result}, result of three-way comparison
  template<class T, class U = T> struct compare_three_way_result;

  template<class T, class U = T>
    using compare_three_way_result_t = compare_three_way_result<T, U>::type;

  // \ref{comparisons.three.way}, class \tcode{compare_three_way}
  struct compare_three_way;

  // \ref{cmp.alg}, comparison algorithms
  inline namespace @\unspec@ {
    inline constexpr @\unspec@ strong_order = @\unspec@;
    inline constexpr @\unspec@ weak_order = @\unspec@;
    inline constexpr @\unspec@ partial_order = @\unspec@;
    inline constexpr @\unspec@ compare_strong_order_fallback = @\unspec@;
    inline constexpr @\unspec@ compare_weak_order_fallback = @\unspec@;
    inline constexpr @\unspec@ compare_partial_order_fallback = @\unspec@;
  }

  // \ref{compare.type}, type ordering
  template<class T, class U>
    struct type_order;

  template<class T, class U>
    constexpr strong_ordering type_order_v = type_order<T, U>::value;
}
\end{codeblock}

\rSec2[cmp.categories]{Comparison category types}

\rSec3[cmp.categories.pre]{Preamble}

\pnum
The types
\tcode{partial_ordering},
\tcode{weak_ordering}, and
\tcode{strong_ordering}
are collectively termed the \defn{comparison category types}.
Each is specified in terms of an exposition-only data member named \tcode{value}
whose value typically corresponds to that of an enumerator
from one of the following exposition-only enumerations:

\begin{codeblock}
enum class @\placeholdernc{ord}@ { @\placeholdernc{equal}@ = 0, @\placeholdernc{equivalent}@ = @\placeholdernc{equal}@, @\placeholdernc{less}@ = -1, @\placeholdernc{greater}@ = 1 }; // \expos
enum class @\placeholdernc{ncmp}@ { @\placeholdernc{unordered}@ = -127 };                                     // \expos
\end{codeblock}

\pnum
\begin{note}
The type \tcode{strong_ordering}
corresponds to the term
total ordering in mathematics.
\end{note}

\pnum
The relational and equality operators for the comparison category types
are specified with an anonymous parameter of unspecified type.
This type shall be selected by the implementation such that
these parameters can accept literal \tcode{0} as a corresponding argument.
\begin{example}
\tcode{nullptr_t}
meets this requirement.
\end{example}
In this context, the behavior of a program that supplies
an argument other than a literal \tcode{0} is undefined.

\pnum
For the purposes of \ref{cmp.categories},
\defn{substitutability} is the property that \tcode{f(a) == f(b)} is \tcode{true}
whenever \tcode{a == b} is \tcode{true},
where \tcode{f} denotes a function that reads only comparison-salient state
that is accessible via the argument's public const members.

\rSec3[cmp.partialord]{Class \tcode{partial_ordering}}

\pnum
The \tcode{partial_ordering} type is typically used
as the result type of a three-way comparison operator\iref{expr.spaceship}
for a type that admits
all of the six two-way comparison operators\iref{expr.rel,expr.eq},
for which equality need not imply substitutability,
and that permits two values to be incomparable.%
\begin{footnote}
That is, \tcode{a < b}, \tcode{a == b}, and \tcode{a > b} might all be \tcode{false}.
\end{footnote}

\indexlibraryglobal{partial_ordering}%
\indexlibrarymember{less}{partial_ordering}%
\indexlibrarymember{equivalent}{partial_ordering}%
\indexlibrarymember{greater}{partial_ordering}%
\indexlibrarymember{unordered}{partial_ordering}%
\begin{codeblock}
namespace std {
  class partial_ordering {
    int @\exposid{value}@;          // \expos
    bool @\exposid{is-ordered}@;    // \expos

    // exposition-only constructors
    constexpr explicit
      partial_ordering(@\placeholder{ord}@ v) noexcept : @\exposid{value}@(int(v)), @\exposid{is-ordered}@(true) {}     // \expos
    constexpr explicit
      partial_ordering(@\placeholder{ncmp}@ v) noexcept : @\exposid{value}@(int(v)), @\exposid{is-ordered}@(false) {}   // \expos

  public:
    // valid values
    static const partial_ordering less;
    static const partial_ordering equivalent;
    static const partial_ordering greater;
    static const partial_ordering unordered;

    // comparisons
    friend constexpr bool operator==(partial_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;
    friend constexpr bool operator< (partial_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator> (partial_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator<=(partial_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator>=(partial_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator< (@\unspec@, partial_ordering v) noexcept;
    friend constexpr bool operator> (@\unspec@, partial_ordering v) noexcept;
    friend constexpr bool operator<=(@\unspec@, partial_ordering v) noexcept;
    friend constexpr bool operator>=(@\unspec@, partial_ordering v) noexcept;
    friend constexpr partial_ordering operator<=>(partial_ordering v, @\unspec@) noexcept;
    friend constexpr partial_ordering operator<=>(@\unspec@, partial_ordering v) noexcept;
  };

  // valid values' definitions
  inline constexpr partial_ordering partial_ordering::less(@\placeholder{ord}@::@\placeholder{less}@);
  inline constexpr partial_ordering partial_ordering::equivalent(@\placeholder{ord}@::@\placeholder{equivalent}@);
  inline constexpr partial_ordering partial_ordering::greater(@\placeholder{ord}@::@\placeholder{greater}@);
  inline constexpr partial_ordering partial_ordering::unordered(@\placeholder{ncmp}@::@\placeholder{unordered}@);
}
\end{codeblock}

\indexlibrarymember{operator==}{partial_ordering}%
\indexlibrarymember{operator<}{partial_ordering}%
\indexlibrarymember{operator>}{partial_ordering}%
\indexlibrarymember{operator<=}{partial_ordering}%
\indexlibrarymember{operator>=}{partial_ordering}%
\begin{itemdecl}
constexpr bool operator==(partial_ordering v, @\unspec@) noexcept;
constexpr bool operator< (partial_ordering v, @\unspec@) noexcept;
constexpr bool operator> (partial_ordering v, @\unspec@) noexcept;
constexpr bool operator<=(partial_ordering v, @\unspec@) noexcept;
constexpr bool operator>=(partial_ordering v, @\unspec@) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
For \tcode{operator@}, \tcode{v.\exposid{is-ordered} \&\& v.\exposid{value} @ 0}.
\end{itemdescr}

\indexlibrarymember{operator<}{partial_ordering}%
\indexlibrarymember{operator>}{partial_ordering}%
\indexlibrarymember{operator<=}{partial_ordering}%
\indexlibrarymember{operator>=}{partial_ordering}%
\begin{itemdecl}
constexpr bool operator< (@\unspec@, partial_ordering v) noexcept;
constexpr bool operator> (@\unspec@, partial_ordering v) noexcept;
constexpr bool operator<=(@\unspec@, partial_ordering v) noexcept;
constexpr bool operator>=(@\unspec@, partial_ordering v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
For \tcode{operator@}, \tcode{v.\exposid{is-ordered} \&\& 0 @ v.\exposid{value}}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{partial_ordering}%
\begin{itemdecl}
constexpr partial_ordering operator<=>(partial_ordering v, @\unspec@) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{partial_ordering}%
\begin{itemdecl}
constexpr partial_ordering operator<=>(@\unspec@, partial_ordering v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v < 0 ?\ partial_ordering::greater :\ v > 0 ?\ partial_ordering::less :\ v}.
\end{itemdescr}

\rSec3[cmp.weakord]{Class \tcode{weak_ordering}}

\pnum
The \tcode{weak_ordering} type is typically used
as the result type of a three-way comparison operator\iref{expr.spaceship}
for a type that admits
all of the six two-way comparison operators\iref{expr.rel,expr.eq}
and for which equality need not imply substitutability.

\indexlibraryglobal{weak_ordering}%
\indexlibrarymember{less}{weak_ordering}%
\indexlibrarymember{equivalent}{weak_ordering}%
\indexlibrarymember{greater}{weak_ordering}%
\begin{codeblock}
namespace std {
  class weak_ordering {
    int @\exposid{value}@;  // \expos

    // exposition-only constructors
    constexpr explicit weak_ordering(@\placeholder{ord}@ v) noexcept : @\exposid{value}@(int(v)) {} // \expos

  public:
    // valid values
    static const weak_ordering less;
    static const weak_ordering equivalent;
    static const weak_ordering greater;

    // conversions
    constexpr operator partial_ordering() const noexcept;

    // comparisons
    friend constexpr bool operator==(weak_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;
    friend constexpr bool operator< (weak_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator> (weak_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator<=(weak_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator>=(weak_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator< (@\unspec@, weak_ordering v) noexcept;
    friend constexpr bool operator> (@\unspec@, weak_ordering v) noexcept;
    friend constexpr bool operator<=(@\unspec@, weak_ordering v) noexcept;
    friend constexpr bool operator>=(@\unspec@, weak_ordering v) noexcept;
    friend constexpr weak_ordering operator<=>(weak_ordering v, @\unspec@) noexcept;
    friend constexpr weak_ordering operator<=>(@\unspec@, weak_ordering v) noexcept;
  };

  // valid values' definitions
  inline constexpr weak_ordering weak_ordering::less(@\placeholder{ord}@::@\placeholder{less}@);
  inline constexpr weak_ordering weak_ordering::equivalent(@\placeholder{ord}@::@\placeholder{equivalent}@);
  inline constexpr weak_ordering weak_ordering::greater(@\placeholder{ord}@::@\placeholder{greater}@);
}
\end{codeblock}

\indexlibrarymember{operator partial_ordering}{weak_ordering}%
\begin{itemdecl}
constexpr operator partial_ordering() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
@\exposid{value}@ == 0 ? partial_ordering::equivalent :
@\exposid{value}@ < 0  ? partial_ordering::less :
             partial_ordering::greater
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator==}{weak_ordering}%
\indexlibrarymember{operator<}{weak_ordering}%
\indexlibrarymember{operator>}{weak_ordering}%
\indexlibrarymember{operator<=}{weak_ordering}%
\indexlibrarymember{operator>=}{weak_ordering}%
\begin{itemdecl}
constexpr bool operator==(weak_ordering v, @\unspec@) noexcept;
constexpr bool operator< (weak_ordering v, @\unspec@) noexcept;
constexpr bool operator> (weak_ordering v, @\unspec@) noexcept;
constexpr bool operator<=(weak_ordering v, @\unspec@) noexcept;
constexpr bool operator>=(weak_ordering v, @\unspec@) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v.\exposid{value} @ 0} for \tcode{operator@}.
\end{itemdescr}

\indexlibrarymember{operator<}{weak_ordering}%
\indexlibrarymember{operator>}{weak_ordering}%
\indexlibrarymember{operator<=}{weak_ordering}%
\indexlibrarymember{operator>=}{weak_ordering}%
\begin{itemdecl}
constexpr bool operator< (@\unspec@, weak_ordering v) noexcept;
constexpr bool operator> (@\unspec@, weak_ordering v) noexcept;
constexpr bool operator<=(@\unspec@, weak_ordering v) noexcept;
constexpr bool operator>=(@\unspec@, weak_ordering v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{0 @ v.\exposid{value}} for \tcode{operator@}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{weak_ordering}%
\begin{itemdecl}
constexpr weak_ordering operator<=>(weak_ordering v, @\unspec@) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{weak_ordering}%
\begin{itemdecl}
constexpr weak_ordering operator<=>(@\unspec@, weak_ordering v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v < 0 ?\ weak_ordering::greater :\ v > 0 ?\ weak_ordering::less :\ v}.
\end{itemdescr}

\rSec3[cmp.strongord]{Class \tcode{strong_ordering}}

\pnum
The \tcode{strong_ordering} type is typically used
as the result type of a three-way comparison operator\iref{expr.spaceship}
for a type that admits
all of the six two-way comparison operators\iref{expr.rel,expr.eq}
and for which equality does imply substitutability.

\indexlibraryglobal{strong_ordering}%
\indexlibrarymember{less}{strong_ordering}%
\indexlibrarymember{equal}{strong_ordering}%
\indexlibrarymember{equivalent}{strong_ordering}%
\indexlibrarymember{greater}{strong_ordering}%
\begin{codeblock}
namespace std {
  class strong_ordering {
    int @\exposid{value}@;  // \expos

    // exposition-only constructors
    constexpr explicit strong_ordering(@\placeholder{ord}@ v) noexcept : @\exposid{value}@(int(v)) {}   // \expos

  public:
    // valid values
    static const strong_ordering less;
    static const strong_ordering equal;
    static const strong_ordering equivalent;
    static const strong_ordering greater;

    // conversions
    constexpr operator partial_ordering() const noexcept;
    constexpr operator weak_ordering() const noexcept;

    // comparisons
    friend constexpr bool operator==(strong_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;
    friend constexpr bool operator< (strong_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator> (strong_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator<=(strong_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator>=(strong_ordering v, @\unspec@) noexcept;
    friend constexpr bool operator< (@\unspec@, strong_ordering v) noexcept;
    friend constexpr bool operator> (@\unspec@, strong_ordering v) noexcept;
    friend constexpr bool operator<=(@\unspec@, strong_ordering v) noexcept;
    friend constexpr bool operator>=(@\unspec@, strong_ordering v) noexcept;
    friend constexpr strong_ordering operator<=>(strong_ordering v, @\unspec@) noexcept;
    friend constexpr strong_ordering operator<=>(@\unspec@, strong_ordering v) noexcept;
  };

  // valid values' definitions
  inline constexpr strong_ordering strong_ordering::less(@\placeholder{ord}@::@\placeholder{less}@);
  inline constexpr strong_ordering strong_ordering::equal(@\placeholder{ord}@::@\placeholder{equal}@);
  inline constexpr strong_ordering strong_ordering::equivalent(@\placeholder{ord}@::@\placeholder{equivalent}@);
  inline constexpr strong_ordering strong_ordering::greater(@\placeholder{ord}@::@\placeholder{greater}@);
}
\end{codeblock}

\indexlibrarymember{operator partial_ordering}{strong_ordering}%
\begin{itemdecl}
constexpr operator partial_ordering() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
@\exposid{value}@ == 0 ? partial_ordering::equivalent :
@\exposid{value}@ < 0  ? partial_ordering::less :
             partial_ordering::greater
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator weak_ordering}{strong_ordering}%
\begin{itemdecl}
constexpr operator weak_ordering() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
@\exposid{value}@ == 0 ? weak_ordering::equivalent :
@\exposid{value}@ < 0  ? weak_ordering::less :
             weak_ordering::greater
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator==}{strong_ordering}%
\indexlibrarymember{operator<}{strong_ordering}%
\indexlibrarymember{operator>}{strong_ordering}%
\indexlibrarymember{operator<=}{strong_ordering}%
\indexlibrarymember{operator>=}{strong_ordering}%
\begin{itemdecl}
constexpr bool operator==(strong_ordering v, @\unspec@) noexcept;
constexpr bool operator< (strong_ordering v, @\unspec@) noexcept;
constexpr bool operator> (strong_ordering v, @\unspec@) noexcept;
constexpr bool operator<=(strong_ordering v, @\unspec@) noexcept;
constexpr bool operator>=(strong_ordering v, @\unspec@) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v.\exposid{value} @ 0} for \tcode{operator@}.
\end{itemdescr}

\indexlibrarymember{operator<}{strong_ordering}%
\indexlibrarymember{operator>}{strong_ordering}%
\indexlibrarymember{operator<=}{strong_ordering}%
\indexlibrarymember{operator>=}{strong_ordering}%
\begin{itemdecl}
constexpr bool operator< (@\unspec@, strong_ordering v) noexcept;
constexpr bool operator> (@\unspec@, strong_ordering v) noexcept;
constexpr bool operator<=(@\unspec@, strong_ordering v) noexcept;
constexpr bool operator>=(@\unspec@, strong_ordering v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{0 @ v.\exposid{value}} for \tcode{operator@}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{strong_ordering}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(strong_ordering v, @\unspec@) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{strong_ordering}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(@\unspec@, strong_ordering v) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{v < 0 ?\ strong_ordering::greater :\ v > 0 ?\ strong_ordering::less :\ v}.
\end{itemdescr}

\rSec2[cmp.common]{Class template \tcode{common_comparison_category}}

\pnum
The type \tcode{common_comparison_category} provides an alias for
the strongest comparison category
to which all of the template arguments can be converted.
\begin{note}
A comparison category type is stronger than another if
they are distinct types and an instance of the former
can be converted to an instance of the latter.
\end{note}

\indexlibraryglobal{common_comparison_category}%
\begin{itemdecl}
template<class... Ts>
struct common_comparison_category {
  using type = @\seebelow@;
};
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
The member \grammarterm{typedef-name} \tcode{type} denotes
the common comparison type\iref{class.spaceship} of \tcode{Ts...},
the expanded parameter pack, or
\keyword{void} if any element of \tcode{Ts}
is not a comparison category type.
\begin{note}
This is \tcode{std::strong_ordering} if the expansion is empty.
\end{note}
\end{itemdescr}

\rSec2[cmp.concept]{Concept \cname{three_way_comparable}}

\begin{codeblock}
template<class T, class Cat>
  concept @\defexposconcept{compares-as}@ =                 // \expos
    @\libconcept{same_as}@<common_comparison_category_t<T, Cat>, Cat>;

template<class T, class U>
  concept @\defexposconcept{partially-ordered-with}@ =      // \expos
    requires(const remove_reference_t<T>& t, const remove_reference_t<U>& u) {
      { t <  u } -> @\exposconcept{boolean-testable}@;
      { t >  u } -> @\exposconcept{boolean-testable}@;
      { t <= u } -> @\exposconcept{boolean-testable}@;
      { t >= u } -> @\exposconcept{boolean-testable}@;
      { u <  t } -> @\exposconcept{boolean-testable}@;
      { u >  t } -> @\exposconcept{boolean-testable}@;
      { u <= t } -> @\exposconcept{boolean-testable}@;
      { u >= t } -> @\exposconcept{boolean-testable}@;
    };
\end{codeblock}

\pnum
Let \tcode{t} and \tcode{u} be
lvalues of types \tcode{const remove_reference_t<T>} and
\tcode{const remove_reference_t<U>}, respectively.
\tcode{T} and \tcode{U} model
\tcode{\exposconcept{partially-ordered-with}<T, U>} only if
\begin{itemize}
\item
  \tcode{t < u},
  \tcode{t <= u},
  \tcode{t > u},
  \tcode{t >= u},
  \tcode{u < t},
  \tcode{u <= t},
  \tcode{u > t}, and
  \tcode{u >= t}
  have the same domain,
\item
  \tcode{bool(t < u) == bool(u > t)} is \tcode{true},
\item
  \tcode{bool(u < t) == bool(t > u)} is \tcode{true},
\item
  \tcode{bool(t <= u) == bool(u >= t)} is \tcode{true}, and
\item
  \tcode{bool(u <= t) == bool(t >= u)} is \tcode{true}.
\end{itemize}

\begin{codeblock}
template<class T, class Cat = partial_ordering>
  concept @\deflibconcept{three_way_comparable}@ =
    @\exposconcept{weakly-equality-comparable-with}@<T, T> &&
    @\exposconcept{partially-ordered-with}@<T, T> &&
    requires(const remove_reference_t<T>& a, const remove_reference_t<T>& b) {
      { a <=> b } -> @\exposconcept{compares-as}@<Cat>;
    };
\end{codeblock}

\pnum
Let \tcode{a} and \tcode{b} be lvalues
of type \tcode{const remove_reference_t<T>}.
\tcode{T} and \tcode{Cat}
model \tcode{\libconcept{three_way_comparable}<T, Cat>} only if
\begin{itemize}
\item
  \tcode{(a <=> b == 0) == bool(a == b)} is \tcode{true},
\item
  \tcode{(a <=> b != 0) == bool(a != b)} is \tcode{true},
\item
  \tcode{((a <=> b) <=> 0)} and \tcode{(0 <=> (b <=> a))} are equal,
\item
  \tcode{(a <=> b < 0) == bool(a < b)} is \tcode{true},
\item
  \tcode{(a <=> b > 0) == bool(a > b)} is \tcode{true},
\item
  \tcode{(a <=> b <= 0) == bool(a <= b)} is \tcode{true},
\item
  \tcode{(a <=> b >= 0) == bool(a >= b)} is \tcode{true}, and
\item
  if \tcode{Cat} is convertible to \tcode{strong_ordering}, \tcode{T} models
  \libconcept{totally_ordered}\iref{concept.totallyordered}.
\end{itemize}

\begin{codeblock}
template<class T, class U, class Cat = partial_ordering>
  concept @\deflibconcept{three_way_comparable_with}@ =
    @\libconcept{three_way_comparable}@<T, Cat> &&
    @\libconcept{three_way_comparable}@<U, Cat> &&
    @\exposconcept{comparison-common-type-with}@<T, U> &&
    @\libconcept{three_way_comparable}@<
      common_reference_t<const remove_reference_t<T>&, const remove_reference_t<U>&>, Cat> &&
    @\exposconcept{weakly-equality-comparable-with}@<T, U> &&
    @\exposconcept{partially-ordered-with}@<T, U> &&
    requires(const remove_reference_t<T>& t, const remove_reference_t<U>& u) {
      { t <=> u } -> @\exposconcept{compares-as}@<Cat>;
      { u <=> t } -> @\exposconcept{compares-as}@<Cat>;
    };
\end{codeblock}

\pnum
Let \tcode{t} and \tcode{t2} be lvalues
denoting distinct equal objects
of types \tcode{const remove_reference_t<T>} and
\tcode{remove_cvref_t<T>}, respectively, and
let \tcode{u} and \tcode{u2} be lvalues denoting distinct equal objects
of types \tcode{const remove_reference_t<U>} and
\tcode{remove_cvref_t<U>}, respectively.
Let \tcode{C} be
\tcode{common_reference_t<const remove_reference_t<T>\&, const remove_reference_t<U>\&>}.
Let \tcode{\exposid{CONVERT_TO_LVALUE}<C>(E)} be defined
as in \ref{concepts.compare.general}.
\tcode{T}, \tcode{U}, and \tcode{Cat}
model \tcode{\libconcept{three_way_comparable_with}<T, U, Cat>} only if
\begin{itemize}
\item
  \tcode{t <=> u} and \tcode{u <=> t} have the same domain,
\item
  \tcode{((t <=> u) <=> 0)} and \tcode{(0 <=> (u <=> t))} are equal,
\item
  \tcode{(t <=> u == 0) == bool(t == u)} is \tcode{true},
\item
  \tcode{(t <=> u != 0) == bool(t != u)} is \tcode{true},
\item
  \tcode{Cat(t <=> u) == Cat(\exposid{CONVERT_TO_LVALUE}<C>(t2) <=>
\exposid{CONVERT_TO_LVALUE}<C>(u2))} is \tcode{true},
\item
  \tcode{(t <=> u < 0) == bool(t < u)} is \tcode{true},
\item
  \tcode{(t <=> u > 0) == bool(t > u)} is \tcode{true},
\item
  \tcode{(t <=> u <= 0) == bool(t <= u)} is \tcode{true},
\item
  \tcode{(t <=> u >= 0) == bool(t >= u)} is \tcode{true}, and
\item
  if \tcode{Cat} is convertible to \tcode{strong_ordering},
  \tcode{T} and \tcode{U} model
  \tcode{\libconcept{totally_ordered_with}<T, U>}\iref{concept.totallyordered}.
\end{itemize}

\rSec2[cmp.result]{Result of three-way comparison}

\pnum
The behavior of a program
that adds specializations for the \tcode{compare_three_way_result} template
defined in this subclause is undefined.

\pnum
For the \tcode{compare_three_way_result} type trait
applied to the types \tcode{T} and \tcode{U},
let \tcode{t} and \tcode{u} denote lvalues of types
\tcode{const remove_reference_t<T>} and \tcode{const remove_reference_t<U>},
respectively.
If the expression \tcode{t <=> u} is well-formed
when treated as an unevaluated operand\iref{expr.context},
the member \grammarterm{typedef-name} \tcode{type}
denotes the type \tcode{decltype(t <=> u)}.
Otherwise, there is no member \tcode{type}.

\rSec2[cmp.alg]{Comparison algorithms}

\indexlibraryglobal{strong_order}%
\pnum
The name \tcode{strong_order} denotes
a customization point object\iref{customization.point.object}.
Given subexpressions \tcode{E} and \tcode{F},
the expression \tcode{strong_order(E, F)}
is expression-equivalent\iref{defns.expression.equivalent} to the following:
\begin{itemize}
\item
  If the decayed types of \tcode{E} and \tcode{F} differ,
  \tcode{strong_order(E, F)} is ill-formed.
\item
  Otherwise, \tcode{strong_ordering(strong_order(E, F))}
  if it is a well-formed expression
  where the meaning of \tcode{strong_order} is established as-if by performing
  argument-dependent lookup only\iref{basic.lookup.argdep}.
\item
  Otherwise, if the decayed type \tcode{T} of \tcode{E} is
  a floating-point type,
  yields a value of type \tcode{strong_ordering}
  that is consistent with the ordering
  observed by \tcode{T}'s comparison operators, and
  if \tcode{numeric_limits<T>::is_iec559} is \tcode{true},
  is additionally consistent with the \tcode{totalOrder} operation
  as specified in \IsoFloatUndated{}.
\item
  Otherwise, \tcode{strong_ordering(compare_three_way()(E, F))}
  if it is a well-formed expression.
\item
  Otherwise, \tcode{strong_order(E, F)} is ill-formed.
\end{itemize}

\begin{note}
Ill-formed cases above result in substitution failure
when \tcode{strong_order(E, F)} appears in the immediate context
of a template instantiation.
\end{note}

\indexlibraryglobal{weak_order}%
\pnum
The name \tcode{weak_order} denotes
a customization point object\iref{customization.point.object}.
Given subexpressions \tcode{E} and \tcode{F},
the expression \tcode{weak_order(E, F)}
is expression-equivalent\iref{defns.expression.equivalent} to the following:
\begin{itemize}
\item
  If the decayed types of \tcode{E} and \tcode{F} differ,
  \tcode{weak_order(E, F)} is ill-formed.
\item
  Otherwise, \tcode{weak_ordering(weak_order(E, F))}
  if it is a well-formed expression
  where the meaning of \tcode{weak_order} is established as-if by performing
  argument-dependent lookup only\iref{basic.lookup.argdep}.
\item
  Otherwise, if the decayed type \tcode{T} of \tcode{E}
  is a floating-point type,
  yields a value of type \tcode{weak_ordering}
  that is consistent with the ordering
  observed by \tcode{T}'s comparison operators and \tcode{strong_order}, and
  if \tcode{numeric_limits<T>::is_iec559} is \tcode{true},
  is additionally consistent with the following equivalence classes,
  ordered from lesser to greater:
  \begin{itemize}
  \item together, all negative NaN values;
  \item negative infinity;
  \item each normal negative value;
  \item each subnormal negative value;
  \item together, both zero values;
  \item each subnormal positive value;
  \item each normal positive value;
  \item positive infinity;
  \item together, all positive NaN values.
  \end{itemize}
\item
  Otherwise, \tcode{weak_ordering(compare_three_way()(E, F))}
  if it is a well-formed expression.
\item
  Otherwise, \tcode{weak_ordering(strong_order(E, F))}
  if it is a well-formed expression.
\item
  Otherwise, \tcode{weak_order(E, F)} is ill-formed.
\end{itemize}

\begin{note}
Ill-formed cases above result in substitution failure
when \tcode{weak_order(E, F)} appears in the immediate context
of a template instantiation.
\end{note}

\indexlibraryglobal{partial_order}%
\pnum
The name \tcode{partial_order} denotes
a customization point object\iref{customization.point.object}.
Given subexpressions \tcode{E} and \tcode{F},
the expression \tcode{partial_order(E, F)}
is expression-equivalent\iref{defns.expression.equivalent} to the following:
\begin{itemize}
\item
  If the decayed types of \tcode{E} and \tcode{F} differ,
  \tcode{partial_order(E, F)} is ill-formed.
\item
  Otherwise, \tcode{partial_ordering(partial_order(E, F))}
  if it is a well-formed expression
  where the meaning of \tcode{partial_order} is established as-if by performing
  argument-dependent lookup only\iref{basic.lookup.argdep}.
\item
  Otherwise, \tcode{partial_ordering(compare_three_way()(E, F))}
  if it is a well-formed expression.
\item
  Otherwise, \tcode{partial_ordering(weak_order(E, F))}
  if it is a well-formed expression.
\item
  Otherwise, \tcode{partial_order(E, F)} is ill-formed.
\end{itemize}

\begin{note}
Ill-formed cases above result in substitution failure
when \tcode{partial_order(E, F)} appears in the immediate context
of a template instantiation.
\end{note}

\indexlibraryglobal{compare_strong_order_fallback}%
\pnum
The name \tcode{compare_strong_order_fallback}
denotes a customization point object\iref{customization.point.object}.
Given subexpressions \tcode{E} and \tcode{F},
the expression \tcode{compare_strong_order_fallback(E, F)}
is expression-equivalent\iref{defns.expression.equivalent} to:
\begin{itemize}
\item
  If the decayed types of \tcode{E} and \tcode{F} differ,
  \tcode{compare_strong_order_fallback(E, F)} is ill-formed.
\item
  Otherwise, \tcode{strong_order(E, F)} if it is a well-formed expression.
\item
  Otherwise, if the expressions \tcode{E == F} and \tcode{E < F}
  are both well-formed and
  each of \tcode{decltype(E == F)} and \tcode{decltype(E < F)} models
  \exposconcept{boolean-testable},
\begin{codeblock}
E == F ? strong_ordering::equal :
E < F  ? strong_ordering::less :
         strong_ordering::greater
\end{codeblock}
except that \tcode{E} and \tcode{F} are evaluated only once.
\item
Otherwise, \tcode{compare_strong_order_fallback(E, F)} is ill-formed.
\end{itemize}

\begin{note}
Ill-formed cases above result in substitution failure
when \tcode{compare_strong_order_fallback(E, F)} appears in the immediate context
of a template instantiation.
\end{note}

\indexlibraryglobal{compare_weak_order_fallback}%
\pnum
The name \tcode{compare_weak_order_fallback} denotes
a customization point object\iref{customization.point.object}.
Given subexpressions \tcode{E} and \tcode{F},
the expression \tcode{compare_weak_order_fallback(E, F)}
is expression-equivalent\iref{defns.expression.equivalent} to:
\begin{itemize}
\item
  If the decayed types of \tcode{E} and \tcode{F} differ,
  \tcode{compare_weak_order_fallback(E, F)} is ill-formed.
\item
  Otherwise, \tcode{weak_order(E, F)} if it is a well-formed expression.
\item
  Otherwise, if the expressions \tcode{E == F} and \tcode{E < F}
  are both well-formed and
  each of \tcode{decltype(E == F)} and \tcode{decltype(E < F)} models
  \exposconcept{boolean-testable},
\begin{codeblock}
E == F ? weak_ordering::equivalent :
E < F  ? weak_ordering::less :
         weak_ordering::greater
\end{codeblock}
except that \tcode{E} and \tcode{F} are evaluated only once.
\item
  Otherwise, \tcode{compare_weak_order_fallback(E, F)} is ill-formed.
\end{itemize}

\begin{note}
Ill-formed cases above result in substitution failure
when \tcode{compare_weak_order_fallback(E, F)} appears in the immediate context
of a template instantiation.
\end{note}

\indexlibraryglobal{compare_partial_order_fallback}%
\pnum
The name \tcode{compare_partial_order_fallback} denotes
a customization point object\iref{customization.point.object}.
Given subexpressions \tcode{E} and \tcode{F},
the expression \tcode{compare_partial_order_fallback(E, F)}
is expression-equivalent\iref{defns.expression.equivalent} to:
\begin{itemize}
\item
  If the decayed types of \tcode{E} and \tcode{F} differ,
  \tcode{compare_partial_order_fallback(E, F)} is ill-formed.
\item
  Otherwise, \tcode{partial_order(E, F)} if it is a well-formed expression.
\item
  Otherwise, if the expressions
  \tcode{E == F}, \tcode{E < F}, and \tcode{F < E}
  are all well-formed and
  each of \tcode{decltype(E == F)}, \tcode{decltype(E < F)}, and
  \tcode{decltype(F < E)} models
  \exposconcept{boolean-testable},
\begin{codeblock}
E == F ? partial_ordering::equivalent :
E < F  ? partial_ordering::less :
F < E  ? partial_ordering::greater :
         partial_ordering::unordered
\end{codeblock}
except that \tcode{E} and \tcode{F} are evaluated only once.
\item
  Otherwise, \tcode{compare_partial_order_fallback(E, F)} is ill-formed.
\end{itemize}

\begin{note}
Ill-formed cases above result in substitution failure
when \tcode{compare_partial_order_fallback(E, F)} appears in the immediate context
of a template instantiation.
\end{note}

\rSec2[compare.type]{Type Ordering}

\pnum
There is an \impldef{total ordering of all types} total ordering of all types.
For any (possibly incomplete) types \tcode{X} and \tcode{Y},
the expression \tcode{\exposid{TYPE-ORDER}(X, Y)} is a constant expression\iref{expr.const.const}
of type \tcode{strong_ordering}\iref{cmp.strongord}.
Its value is \tcode{strong_ordering::less} if \tcode{X} precedes \tcode{Y}
in this implementation-defined total order,
\tcode{strong_ordering::greater} if \tcode{Y} precedes \tcode{X}, and
\tcode{strong_ordering::equal} if they are the same type.
\begin{note}
\tcode{int}, \tcode{const int} and \tcode{int\&} are different types.
\end{note}
\begin{note}
This ordering need not be consistent with the one induced by \tcode{type_info::before}.
\end{note}
\begin{note}
The ordering of TU-local types from different translation units is not observable,
because the necessary specialization of \tcode{type_order} is impossible to name.
\end{note}

\indexlibraryglobal{type_order}%
\begin{itemdecl}
template<class T, class U> struct type_order {
  static constexpr strong_ordering @\libmember{value}{type_order}@ = @\exposid{TYPE-ORDER}@(T, U);

  using @\libmember{value_type}{type_order}@ = strong_ordering;

  constexpr @\libmember{operator value_type}{type_order}@() const noexcept { return value; }
  constexpr value_type @\libmember{operator()}{type_order}@() const noexcept { return value; }
};
\end{itemdecl}

\begin{itemdescr}
\pnum
If an explicit specialization or partial specialization of \tcode{type_order} is declared,
the program is ill-formed.

\pnum
\recommended
The order should be lexicographical on parameter-type-lists and template argument lists.
\end{itemdescr}

\rSec1[support.coroutine]{Coroutines}

\rSec2[support.coroutine.general]{General}

\pnum
The header \libheaderdef{coroutine}
defines several types providing
compile and run-time support for
coroutines in a \Cpp{} program.

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

\indexheader{coroutine}%
\indexlibraryglobal{noop_coroutine_handle}%
\begin{codeblock}
// all freestanding
#include <compare>              // see \ref{compare.syn}

namespace std {
  // \ref{coroutine.traits}, coroutine traits
  template<class R, class... ArgTypes>
    struct coroutine_traits;

  // \ref{coroutine.handle}, coroutine handle
  template<class Promise = void>
    struct coroutine_handle;

  // \ref{coroutine.handle.compare}, comparison operators
  constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
  constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;

  // \ref{coroutine.handle.hash}, hash support
  template<class T> struct hash;
  template<class P> struct hash<coroutine_handle<P>>;

  // \ref{coroutine.noop}, no-op coroutines
  struct noop_coroutine_promise;

  template<> struct coroutine_handle<noop_coroutine_promise>;
  using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;

  noop_coroutine_handle noop_coroutine() noexcept;

  // \ref{coroutine.trivial.awaitables}, trivial awaitables
  struct suspend_never;
  struct suspend_always;
}
\end{codeblock}

\rSec2[coroutine.traits]{Coroutine traits}

\rSec3[coroutine.traits.general]{General}

\pnum
Subclause \ref{coroutine.traits} defines requirements on classes representing
\term{coroutine traits},
and defines the class template
\tcode{coroutine_traits}
that meets those requirements.

\rSec3[coroutine.traits.primary]{Class template \tcode{coroutine_traits}}

\indexlibraryglobal{coroutine_traits}%
\pnum
The header \libheader{coroutine} defines the primary template
\tcode{coroutine_traits} such that
if \tcode{ArgTypes} is a parameter pack of types and
if the \grammarterm{qualified-id} \tcode{R::promise_type} is valid and
denotes a type\iref{temp.deduct},
then \tcode{coroutine_traits<R, ArgTypes...>} has the following publicly
accessible member:

\begin{codeblock}
using promise_type = R::promise_type;
\end{codeblock}

Otherwise, \tcode{coroutine_traits<R, ArgTypes...>} has no members.

\pnum
Program-defined specializations of this template shall define a publicly
accessible nested type named \tcode{promise_type}.

\rSec2[coroutine.handle]{Class template \tcode{coroutine_handle}}

\rSec3[coroutine.handle.general]{General}

\indexlibraryglobal{coroutine_handle}%
\begin{codeblock}
namespace std {
  template<>
  struct coroutine_handle<void> {
    // \ref{coroutine.handle.con}, construct/reset
    constexpr coroutine_handle() noexcept;
    constexpr coroutine_handle(nullptr_t) noexcept;
    coroutine_handle& operator=(nullptr_t) noexcept;

    // \ref{coroutine.handle.export.import}, export/import
    constexpr void* address() const noexcept;
    static constexpr coroutine_handle from_address(void* addr);

    // \ref{coroutine.handle.observers}, observers
    constexpr explicit operator bool() const noexcept;
    bool done() const;

    // \ref{coroutine.handle.resumption}, resumption
    void operator()() const;
    void resume() const;
    void destroy() const;

  private:
    void* ptr;  // \expos
  };

  template<class Promise>
  struct coroutine_handle {
    // \ref{coroutine.handle.con}, construct/reset
    constexpr coroutine_handle() noexcept;
    constexpr coroutine_handle(nullptr_t) noexcept;
    static coroutine_handle from_promise(Promise&);
    coroutine_handle& operator=(nullptr_t) noexcept;

    // \ref{coroutine.handle.export.import}, export/import
    constexpr void* address() const noexcept;
    static constexpr coroutine_handle from_address(void* addr);

    // \ref{coroutine.handle.conv}, conversion
    constexpr operator coroutine_handle<>() const noexcept;

    // \ref{coroutine.handle.observers}, observers
    constexpr explicit operator bool() const noexcept;
    bool done() const;

    // \ref{coroutine.handle.resumption}, resumption
    void operator()() const;
    void resume() const;
    void destroy() const;

    // \ref{coroutine.handle.promise}, promise access
    Promise& promise() const;

  private:
    void* ptr;  // \expos
  };
}
\end{codeblock}

\pnum
An object of type
\tcode{coroutine_handle<T>} is called a \term{coroutine handle}
and can be used to refer to a suspended or executing coroutine.
A \tcode{coroutine_handle} object whose
member \tcode{address()} returns a null pointer value
does not refer to any
coroutine.
Two \tcode{coroutine_handle} objects refer to the same coroutine
if and only if their member \tcode{address()} returns the same non-null value.

\pnum
If a program declares an explicit or partial specialization of
\tcode{coroutine_handle}, the behavior is undefined.

\rSec3[coroutine.handle.con]{Construct/reset}

\indexlibraryctor{coroutine_handle}%
\begin{itemdecl}
constexpr coroutine_handle() noexcept;
constexpr coroutine_handle(nullptr_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{address() == nullptr}.
\end{itemdescr}

\indexlibrarymember{from_promise}{coroutine_handle}%
\begin{itemdecl}
static coroutine_handle from_promise(Promise& p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is a reference to a promise object of a coroutine.

\pnum
\ensures
\tcode{addressof(h.promise()) == addressof(p)}.

\pnum
\returns
A coroutine handle \tcode{h} referring to the coroutine.
\end{itemdescr}

\indexlibrarymember{operator=}{coroutine_handle}%
\begin{itemdecl}
coroutine_handle& operator=(nullptr_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{address() == nullptr}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec3[coroutine.handle.conv]{Conversion}

\indexlibrarymember{operator coroutine_handle<>}{coroutine_handle}%
\begin{itemdecl}
constexpr operator coroutine_handle<>() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return coroutine_handle<>::from_address(address());}
\end{itemdescr}

\rSec3[coroutine.handle.export.import]{Export/import}

\indexlibrarymember{address}{coroutine_handle}%
\begin{itemdecl}
constexpr void* address() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ptr}.
\end{itemdescr}

\indexlibrarymember{from_address}{coroutine_handle}%
\begin{itemdecl}
static constexpr coroutine_handle<> coroutine_handle<>::from_address(void* addr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{addr} was obtained via a prior call to \tcode{address}
on an object whose type is a specialization of \tcode{coroutine_handle}.

\pnum
\ensures
\tcode{from_address(address()) == *this}.
\end{itemdescr}

\indexlibrarymember{from_address}{coroutine_handle}%
\begin{itemdecl}
static constexpr coroutine_handle<Promise> coroutine_handle<Promise>::from_address(void* addr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{addr} was obtained via a prior call to \tcode{address}
on an object of type \cv{}~\tcode{coroutine_handle<Promise>}.

\pnum
\ensures
\tcode{from_address(address()) == *this}.
\end{itemdescr}

\rSec3[coroutine.handle.observers]{Observers}

\indexlibrarymember{operator bool}{coroutine_handle}%
\begin{itemdecl}
constexpr explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{address() != nullptr}.
\end{itemdescr}

\indexlibrarymember{done}{coroutine_handle}%
\begin{itemdecl}
bool done() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{*this} refers to a suspended coroutine.

\pnum
\returns
\tcode{true} if the coroutine is suspended at its
final suspend point, otherwise \tcode{false}.
\end{itemdescr}

\rSec3[coroutine.handle.resumption]{Resumption}

\pnum
Resuming a coroutine via \tcode{resume}, \tcode{operator()}, or \tcode{destroy}
on an execution agent other than the one on which it was suspended
has \impldef{resuming a coroutine on a different execution agent} behavior
unless
each execution agent either is
an instance of \tcode{std::thread} or \tcode{std::jthread},
or is the thread that executes \tcode{main}.
\begin{note}
A coroutine that is resumed on a different execution agent should
avoid relying on consistent thread identity throughout, such as holding
a mutex object across a suspend point.
\end{note}
\begin{note}
A concurrent resumption of the coroutine can result in a data race.
\end{note}

\indexlibrarymember{operator()}{coroutine_handle}%
\indexlibrarymember{resume}{coroutine_handle}%
\begin{itemdecl}
void operator()() const;
void resume() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{*this} refers to a suspended coroutine.
The coroutine is not suspended at its final suspend point.

\pnum
\effects
Resumes the execution of the coroutine.
\end{itemdescr}

\indexlibrarymember{destroy}{coroutine_handle}%
\begin{itemdecl}
void destroy() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{*this} refers to a suspended coroutine.

\pnum
\effects
Destroys the coroutine\iref{dcl.fct.def.coroutine}.
\end{itemdescr}

\rSec3[coroutine.handle.promise]{Promise access}

\indexlibrarymember{promise}{coroutine_handle}%
\begin{itemdecl}
Promise& promise() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{*this} refers to a coroutine.

\pnum
\returns
A reference to the promise of the coroutine.
\end{itemdescr}

\rSec3[coroutine.handle.compare]{Comparison operators}

\indexlibrarymember{operator==}{coroutine_handle}%
\indexlibrarymember{operator"!=}{coroutine_handle}%
\begin{itemdecl}
constexpr bool operator==(coroutine_handle<> x, coroutine_handle<> y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.address() == y.address()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{coroutine_handle}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(coroutine_handle<> x, coroutine_handle<> y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{compare_three_way()(x.address(), y.address())}.
\end{itemdescr}

\rSec3[coroutine.handle.hash]{Hash support}

\indexlibrarymember{hash}{coroutine_handle}%
\begin{itemdecl}
template<class P> struct hash<coroutine_handle<P>>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization is enabled\iref{unord.hash}.
\end{itemdescr}

\rSec2[coroutine.noop]{No-op coroutines}

\rSec3[coroutine.promise.noop]{Class \tcode{noop_coroutine_promise}}

\indexlibraryglobal{noop_coroutine_promise}%
\begin{itemdecl}
struct noop_coroutine_promise {};
\end{itemdecl}

\begin{itemdescr}
\pnum
The class \tcode{noop_coroutine_promise} defines the promise type for
the coroutine referred to
by \tcode{noop_coroutine_handle}\iref{coroutine.syn}.
\end{itemdescr}

\rSec3[coroutine.handle.noop]{Class \tcode{coroutine_handle<noop_coroutine_promise>}}

\rSec4[coroutine.handle.noop.general]{General}

\indexlibraryglobal{coroutine_handle<noop_coroutine_promise>}%
\begin{codeblock}
namespace std {
  template<>
  struct coroutine_handle<noop_coroutine_promise> {
    // \ref{coroutine.handle.noop.conv}, conversion
    constexpr operator coroutine_handle<>() const noexcept;

    // \ref{coroutine.handle.noop.observers}, observers
    constexpr explicit operator bool() const noexcept;
    constexpr bool done() const noexcept;

    // \ref{coroutine.handle.noop.resumption}, resumption
    constexpr void operator()() const noexcept;
    constexpr void resume() const noexcept;
    constexpr void destroy() const noexcept;

    // \ref{coroutine.handle.noop.promise}, promise access
    noop_coroutine_promise& promise() const noexcept;

    // \ref{coroutine.handle.noop.address}, address
    constexpr void* address() const noexcept;
  private:
    coroutine_handle(@\unspec@);
    void* ptr;  // \expos
  };
}
\end{codeblock}

\rSec4[coroutine.handle.noop.conv]{Conversion}

\indexlibrarymember{operator coroutine_handle<>}{coroutine_handle<noop_coroutine_promise>}%
\begin{itemdecl}
constexpr operator coroutine_handle<>() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return coroutine_handle<>::from_address(address());}
\end{itemdescr}

\rSec4[coroutine.handle.noop.observers]{Observers}

\indexlibrarymember{operator bool}{coroutine_handle<noop_coroutine_promise>}%
\begin{itemdecl}
constexpr explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true}.
\end{itemdescr}

\indexlibrarymember{done}{coroutine_handle<noop_coroutine_promise>}%
\begin{itemdecl}
constexpr bool done() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{false}.
\end{itemdescr}

\rSec4[coroutine.handle.noop.resumption]{Resumption}

\indexlibrarymember{operator()}{coroutine_handle<noop_coroutine_promise>}%
\indexlibrarymember{resume}{coroutine_handle<noop_coroutine_promise>}%
\indexlibrarymember{destroy}{coroutine_handle<noop_coroutine_promise>}%
\begin{itemdecl}
constexpr void operator()() const noexcept;
constexpr void resume() const noexcept;
constexpr void destroy() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
None.

\pnum
\remarks
If \tcode{noop_coroutine_handle} is converted to \tcode{coroutine_handle<>},
calls to \tcode{operator()}, \tcode{resume} and \tcode{destroy} on that handle
will also have no observable effects.
\end{itemdescr}

\rSec4[coroutine.handle.noop.promise]{Promise access}

\indexlibrarymember{promise}{coroutine_handle<noop_coroutine_promise>}%
\begin{itemdecl}
noop_coroutine_promise& promise() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A reference to the promise object associated with this
coroutine handle.
\end{itemdescr}

\rSec4[coroutine.handle.noop.address]{Address}

\indexlibrarymember{address}{coroutine_handle<noop_coroutine_promise>}%
\begin{itemdecl}
constexpr void* address() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ptr}.

\pnum
\remarks
A \tcode{noop_coroutine_handle}'s \tcode{ptr} is always a
non-null pointer value.
\end{itemdescr}

\rSec3[coroutine.noop.coroutine]{Function \tcode{noop_coroutine}}

\indexlibraryglobal{noop_coroutine}%
\begin{itemdecl}
noop_coroutine_handle noop_coroutine() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A handle to a coroutine that has no observable effects
when resumed or destroyed.

\pnum
\remarks
A handle returned from \tcode{noop_coroutine} may or may not
compare equal to a handle returned from another invocation
of \tcode{noop_coroutine}.
\end{itemdescr}

\rSec2[coroutine.trivial.awaitables]{Trivial awaitables}

\indexlibraryglobal{suspend_never}%
\indexlibrarymember{await_ready}{suspend_never}%
\indexlibrarymember{await_suspend}{suspend_never}%
\indexlibrarymember{await_resume}{suspend_never}%
\indexlibraryglobal{suspend_always}%
\indexlibrarymember{await_ready}{suspend_always}%
\indexlibrarymember{await_suspend}{suspend_always}%
\indexlibrarymember{await_resume}{suspend_always}%
\begin{codeblock}
namespace std {
  struct suspend_never {
    constexpr bool await_ready() const noexcept { return true; }
    constexpr void await_suspend(coroutine_handle<>) const noexcept {}
    constexpr void await_resume() const noexcept {}
  };
  struct suspend_always {
    constexpr bool await_ready() const noexcept { return false; }
    constexpr void await_suspend(coroutine_handle<>) const noexcept {}
    constexpr void await_resume() const noexcept {}
  };
}
\end{codeblock}

\pnum
\begin{note}
The types \tcode{suspend_never} and \tcode{suspend_always} can be used
to indicate that an \grammarterm{await-expression} either never
suspends or always suspends, and in either case does not produce a value.
\end{note}

\rSec1[support.runtime]{Other runtime support}

\rSec2[support.runtime.general]{General}

\pnum
\indexlibraryglobal{getenv}%
\indexlibraryglobal{system}%
Headers
\libheader{csetjmp} (nonlocal jumps),
\libheader{csignal} (signal handling),
\libheader{cstdarg} (variable arguments),
and
\libheader{cstdlib} (runtime environment \tcode{getenv}, \tcode{system}),
provide further compatibility with C code.

\pnum
Calls to the function
\indexlibraryglobal{getenv}%
\tcode{getenv}\iref{cstdlib.syn} shall not introduce a data
race\iref{res.on.data.races} provided that nothing modifies the environment.
\begin{note}
Calls to the POSIX functions
\indexlibraryglobal{setenv}%
\tcode{setenv} and
\indexlibraryglobal{putenv}%
\tcode{putenv} modify the
environment.
\end{note}

\pnum
A call to the \tcode{setlocale} function\iref{c.locales}
may introduce a data race with other
calls to the \tcode{setlocale} function or with calls to functions that are
affected by the current C locale. The implementation shall behave as if no
library function other than \tcode{locale::global} calls the \tcode{setlocale}
function.

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

\indexheader{cstdarg}%
\begin{codeblock}
// all freestanding
#define __STDC_VERSION_STDARG_H__ 202311L

namespace std {
  using @\libglobal{va_list}@ = @\seebelow@;
}

#define @\libmacro{va_arg}@(V, P) @\seebelow@
#define @\libmacro{va_copy}@(VDST, VSRC) @\seebelow@
#define @\libmacro{va_end}@(V) @\seebelow@
#define @\libmacro{va_start}@(V, ...) @\seebelow@
\end{codeblock}

\pnum
The contents of the header \libheaderdef{cstdarg} are the same as the C
standard library header \libheader{stdarg.h}, with the following changes:
\begin{itemize}
\item
In lieu of the default argument promotions specified in \IsoC{} 6.5.3.3,
the definition in~\ref{expr.call} applies.
\item
If more than one argument is present for \tcode{va_start} and
any of the second or subsequent arguments
expands to include unbalanced parentheses, or
a preprocessing token that does not convert to a token,
the program is ill-formed, no diagnostic required.
The preprocessing tokens
comprising the second and subsequent arguments to \tcode{va_start} (if any)
are discarded.
\begin{note}
\tcode{va_start} accepts a second argument
for compatibility with prior revisions of \Cpp{}.
\end{note}
\end{itemize}

\xrefc{7.16}

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

\indexlibraryglobal{jmp_buf}%
\indexlibraryglobal{longjmp}%
\indexlibraryglobal{setjmp}%
\begin{codeblock}
#define __STDC_VERSION_SETJMP_H__ 202311L

namespace std {
  using jmp_buf = @\seebelow@;
  [[noreturn]] void longjmp(jmp_buf env, int val);
}

#define setjmp(env) @\seebelow@
\end{codeblock}

\pnum
The contents of the header \libheaderdef{csetjmp} are the same as the C
standard library header \libheader{setjmp.h}.

\pnum
The function signature
\indexlibraryglobal{longjmp}%
\tcode{longjmp(jmp_buf jbuf, int val)}
has more restricted behavior in this document.
A \tcode{setjmp}/\tcode{longjmp} call pair has undefined
behavior if replacing the \tcode{setjmp} and \tcode{longjmp}
by \keyword{catch} and \tcode{throw} would invoke any non-trivial destructors for any objects
with automatic storage duration.
A call to \tcode{setjmp} or \tcode{longjmp} has undefined
behavior if invoked in a suspension context of a coroutine\iref{expr.await}.

\xrefc{7.13}

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

\indexlibraryglobal{sig_atomic_t}%
\indexlibraryglobal{signal}%
\indexlibraryglobal{raise}%
\indexlibraryglobal{SIG_IGN}%
\indexlibraryglobal{SIGABRT}%
\indexlibraryglobal{SIGFPE}%
\indexlibraryglobal{SIGILL}%
\indexlibraryglobal{SIGINT}%
\indexlibraryglobal{SIGSEGV}%
\indexlibraryglobal{SIGTERM}%
\indexlibraryglobal{SIG_DFL}%
\indexlibraryglobal{SIG_ERR}%
\begin{codeblock}
namespace std {
  using sig_atomic_t = @\seebelow@;

  // \ref{support.signal}, signal handlers
  extern "C" using @\placeholdernc{signal-handler}@ = void(int);  // \expos
  @\placeholder{signal-handler}@* signal(int sig, @\placeholder{signal-handler}@* func);

  int raise(int sig);
}

#define SIG_DFL @\seebelow@
#define SIG_ERR @\seebelow@
#define SIG_IGN @\seebelow@
#define SIGABRT @\seebelow@
#define SIGFPE @\seebelow@
#define SIGILL @\seebelow@
#define SIGINT @\seebelow@
#define SIGSEGV @\seebelow@
#define SIGTERM @\seebelow@
\end{codeblock}

\pnum
The contents of the header \libheaderdef{csignal} are the same as the C
standard library header \libheader{signal.h}.

\rSec2[support.signal]{Signal handlers}

\pnum
A call to the function \tcode{signal} synchronizes with any resulting
invocation of the signal handler so installed.

\pnum
A \defn{plain lock-free atomic operation} is
an invocation of a function \tcode{f} from \ref{atomics},
such that:
\begin{itemize}
\item
\tcode{f} is the function \tcode{atomic_is_lock_free()}, or

\item
\tcode{f} is the member function \tcode{is_lock_free()}, or

\item
\tcode{f} is a non-static member function of class \tcode{atomic_flag}, or

\item
\tcode{f} is a non-member function, and
the first parameter of \tcode{f} has type \cv{}~\tcode{atomic_flag*}, or

\item
\tcode{f} is a non-static member function invoked on an object \tcode{A},
such that \tcode{A.is_lock_free()} yields \tcode{true}, or

\item
\tcode{f} is a non-member function, and
for every pointer-to-atomic argument \tcode{A} passed to \tcode{f},
\tcode{atomic_is_lock_free(A)} yields \tcode{true}.
\end{itemize}

\pnum
\indextext{signal-safe!evaluation|see{evaluation, signal-safe}}%
An evaluation is \defnx{signal-safe}{evaluation!signal-safe} unless it includes one of the following:
\begin{itemize}
\item
a call to any standard library function,
except for plain lock-free atomic operations and
functions explicitly identified as signal-safe;
\begin{note}
This implicitly excludes the use of \keyword{new} and \keyword{delete} expressions
that rely on a library-provided memory allocator.
\end{note}

\item
an access to an object with thread storage duration;

\item
a \keyword{dynamic_cast} expression;

\item
throwing of an exception;

\item
control entering a \grammarterm{try-block} or \grammarterm{function-try-block};

\item
initialization of a variable with static storage duration
requiring dynamic initialization\iref{basic.start.dynamic,stmt.dcl}
\begin{footnote}
Such initialization can occur because it is the first odr-use\iref{term.odr.use} of that variable.
\end{footnote}
; or

\item
waiting for the completion of the initialization of a variable with static storage duration\iref{stmt.dcl}.
\end{itemize}

A signal handler invocation has undefined behavior if it includes
an evaluation that is not signal-safe.

\pnum
\indextext{signal-safe!\idxcode{signal}}%
The function \tcode{signal} is signal-safe if it is invoked
with the first argument equal to the signal number
corresponding to the signal that caused the invocation of the handler.

\xrefc{7.14}

\rSec1[support.c.headers]{C headers}

\rSec2[support.c.headers.general]{General}

\pnum
For compatibility with the
\indextext{library!C standard}%
C standard library, the \Cpp{} standard library provides
the \defnx{C headers}{headers!C library} shown in \tref{c.headers}.
The intended use of these headers is for interoperability only.
It is possible that \Cpp{} source files need to include
one of these headers in order to be valid C.
Source files that are not intended to also be valid C
should not use any of the C headers.

\begin{note}
The C headers either have no effect,
such as \libheaderref{stdbool.h} and \libheaderref{stdalign.h}, or
otherwise the corresponding header of the form \tcode{<c\placeholder{name}>}
provides the same facilities and
assuredly defines them in namespace \tcode{std}.
\end{note}
\begin{example}
The following source file is both valid \Cpp{} and valid C.
Viewed as \Cpp{}, it declares a function with C language linkage;
viewed as C it simply declares a function (and provides a prototype).
\begin{codeblock}
#include <uchar.h>      // for \tcode{char8_t} in C, not necessary in \Cpp{}
#include <stddef.h>     // for \tcode{size_t}

#ifdef __cplusplus      // see \ref{cpp.predefined}
extern "C"              // see \ref{dcl.link}
#endif
void f(char8_t s[], size_t n);
\end{codeblock}
\end{example}

\begin{multicolfloattable}{C headers}{c.headers}
{lllll}
\libheaderdef{assert.h} \\
\libheader{complex.h} \\
\libheaderdef{ctype.h} \\
\libheaderdef{errno.h} \\
\libheaderdef{fenv.h} \\
\libheaderdef{float.h} \\
\columnbreak
\libheaderdef{inttypes.h} \\
\libheader{iso646.h} \\
\libheaderdef{limits.h} \\
\libheaderdef{locale.h} \\
\libheaderdef{math.h} \\
\libheaderdef{setjmp.h} \\
\columnbreak
\libheaderdef{signal.h} \\
\libheader{stdalign.h} \\
\libheaderdef{stdarg.h} \\
\libheader{stdatomic.h} \\
\libheader{stdbit.h} \\
\libheader{stdbool.h} \\
\columnbreak
\libheader{stdckdint.h} \\
\libheaderdef{stddef.h} \\
\libheaderdef{stdint.h} \\
\libheaderdef{stdio.h} \\
\libheaderdef{stdlib.h} \\
\libheaderdef{string.h} \\
\columnbreak
\libheader{tgmath.h} \\
\libheaderdef{time.h} \\
\libheaderdef{uchar.h} \\
\libheaderdef{wchar.h} \\
\libheaderdef{wctype.h} \\
\end{multicolfloattable}

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

\indexheader{complex.h}%
\begin{codeblock}
#include <complex>
\end{codeblock}

\pnum
The header \libheader{complex.h}
behaves as if it simply includes the header
\libheaderref{complex}.

\pnum
\begin{note}
Names introduced by \libheader{complex} in namespace \tcode{std}
are not placed into the global namespace scope by \libheader{complex.h}.
\end{note}

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

\indexheader{iso646.h}%
\pnum
The \Cpp{} header \libheader{iso646.h} is empty.
\begin{note}
\tcode{and},
\tcode{and_eq},
\tcode{bitand},
\tcode{bitor},
\tcode{compl},
\tcode{not_eq},
\tcode{not},
\tcode{or},
\tcode{or_eq},
\tcode{xor}, and
\tcode{xor_eq}
are keywords in \Cpp{}\iref{lex.key}.
\end{note}

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

\indexheader{stdalign.h}%
\pnum
The contents of the \Cpp{} header \libheader{stdalign.h} are the same as the C
standard library header \libheader{stdalign.h}.

\xrefc{7.15}

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

\indexheader{stdbool.h}%
\pnum
The contents of the \Cpp{} header \libheader{stdbool.h} are the same as the C
standard library header \libheader{stdbool.h}.

\xrefc{7.19}

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

\indexheader{tgmath.h}%
\begin{codeblock}
#include <cmath>
#include <complex>
\end{codeblock}

\pnum
The header \libheader{tgmath.h}
behaves as if it simply includes the headers
\libheaderref{cmath} and
\libheaderref{complex}.

\pnum
\begin{note}
The overloads provided in C by type-generic macros
are already provided in \libheader{complex} and \libheader{cmath}
by ``sufficient'' additional overloads.
\end{note}

\pnum
\begin{note}
Names introduced by \libheader{cmath} or \libheader{complex}
in namespace \tcode{std}
are not placed into the global namespace scope by \libheader{tgmath.h}.
\end{note}

\rSec2[support.c.headers.other]{Other C headers}

\pnum
Every C header
other than
\libheaderref{complex.h},
\libheaderref{iso646.h},
\libheaderref{stdalign.h},\newline
\libheaderref{stdatomic.h},
\libheaderref{stdbit.h},
\libheaderref{stdbool.h},
\libheaderref{stdckdint.h}, and\newline
\libheaderref{tgmath.h},
each of
which has a name of the form
\indextext{header!C}%
\tcode{<\placeholder{name}.h>},
behaves as if each name placed in the standard library namespace by
the corresponding
\tcode{<c\placeholder{name}>}
header is placed within
the global namespace scope,
except for the functions described in \ref{sf.cmath},
the \tcode{std::lerp} function overloads\iref{c.math.lerp},
the declaration of \tcode{std::byte}\iref{cstddef.syn}, and
the functions and function templates described in \ref{support.types.byteops}.
It is unspecified whether these names are first declared or defined within
namespace scope\iref{basic.scope.namespace} of the namespace
\tcode{std} and are then injected into the global namespace scope by
explicit \grammarterm{using-declaration}{s}\iref{namespace.udecl}.

\pnum
\begin{example}
The header \libheader{cstdlib} assuredly
provides its declarations and definitions within the namespace
\tcode{std}. It may also provide these names within the
global namespace.
The header \libheader{stdlib.h}
assuredly provides the same declarations and definitions within
the global namespace,
much as in \IsoCUndated{}. It may also provide these names within
the namespace \tcode{std}.
\end{example}
