%!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 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{}, \tcode{} \\ \rowsep \ref{support.limits} & Implementation properties & \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{support.arith.types} & Arithmetic types & \tcode{}, \tcode{} \\ \rowsep \ref{support.start.term} & Start and termination & \tcode{} \\ \rowsep \ref{support.dynamic} & Dynamic memory management & \tcode{} \\ \rowsep \ref{support.rtti} & Type identification & \tcode{} \\ \rowsep \ref{support.srcloc} & Source location & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{cmp} & Comparisons & \tcode{} \\ \rowsep \ref{support.coroutine} & Coroutines & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \end{libsumtab} \rSec1[support.types]{Common definitions} \rSec2[cstddef.syn]{Header \tcode{} 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 constexpr byte& operator<<=(byte& b, IntType shift) noexcept; template constexpr byte operator<<(byte b, IntType shift) noexcept; template constexpr byte& operator>>=(byte& b, IntType shift) noexcept; template 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 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 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.19} \rSec2[cstdlib.syn]{Header \tcode{} 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@; using ldiv_t = @\seebelow@; using lldiv_t = @\seebelow@; } #define NULL @\seebelow@ // freestanding #define EXIT_FAILURE @\seebelow@ #define EXIT_SUCCESS @\seebelow@ #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* malloc(size_t size); void* realloc(void* ptr, size_t size); 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); 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, const void* base, size_t nmemb, size_t size, @\placeholder{c-compare-pred}@*@\itcorr[-1]@ compar); void* bsearch(const void* key, const void* base, size_t nmemb, 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); void qsort(void* base, size_t nmemb, size_t size, @\placeholder{compare-pred}@*@\itcorr[-1]@ compar); // \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); constexpr long int abs(long int j); constexpr long long int abs(long long int j); constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ j); constexpr long int labs(long int j); constexpr long long int llabs(long long int j); constexpr div_t div(int numer, int denom); constexpr ldiv_t div(long int numer, long int denom); // see \ref{library.c} constexpr lldiv_t div(long long int numer, long long int denom); // see \ref{library.c} constexpr ldiv_t ldiv(long int numer, long int denom); constexpr lldiv_t lldiv(long long int numer, long long int denom); } \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 type \keyword{wchar_t}, 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.22} \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.19} \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 trivial 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}. \xrefc{7.19} \rSec2[support.types.byteops]{\tcode{byte} type operations} \indexlibrarymember{operator<<=}{byte}% \begin{itemdecl} template constexpr byte& operator<<=(byte& b, IntType shift) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: \tcode{return b = b << shift;} \end{itemdescr} \indexlibrarymember{operator<<}{byte}% \begin{itemdecl} template constexpr byte operator<<(byte b, IntType shift) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: \begin{codeblock} return static_cast(static_cast(b) << shift); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator>>=}{byte}% \begin{itemdecl} template constexpr byte& operator>>=(byte& b, IntType shift) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: \tcode{return b = b >> shift;} \end{itemdescr} \indexlibrarymember{operator>>}{byte}% \begin{itemdecl} template constexpr byte operator>>(byte b, IntType shift) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: \begin{codeblock} return static_cast(static_cast(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(static_cast(l) | static_cast(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(static_cast(l) & static_cast(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(static_cast(l) ^ static_cast(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(~static_cast(b)); \end{codeblock} \end{itemdescr} \indexlibrarymember{to_integer}{byte}% \begin{itemdecl} template constexpr IntType to_integer(byte b) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_integral_v} is \tcode{true}. \pnum \effects Equivalent to: \tcode{return static_cast(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{} synopsis} \pnum The header \libheaderdef{version} supplies implementation-dependent information about the \Cpp{} standard library (e.g., version number and release date). \pnum 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 \Cpp{} might replace the values of these macros with greater values. \end{note} \begin{codeblock} #define @\defnlibxname{cpp_lib_addressof_constexpr}@ 201603L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_algorithm_iterator_requirements}@ 202207L // also in \libheader{algorithm}, \libheader{numeric}, \libheader{memory} #define @\defnlibxname{cpp_lib_allocate_at_least}@ 202302L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_allocator_traits_is_always_equal}@ 201411L // 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_adaptor_iterator_pair_constructor}@ 202106L // also in \libheader{stack}, \libheader{queue} #define @\defnlibxname{cpp_lib_any}@ 201606L // also in \libheader{any} #define @\defnlibxname{cpp_lib_apply}@ 201603L // also in \libheader{tuple} #define @\defnlibxname{cpp_lib_array_constexpr}@ 201811L // also in \libheader{iterator}, \libheader{array} #define @\defnlibxname{cpp_lib_as_const}@ 201510L // 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_assume_aligned}@ 201811L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_flag_test}@ 201907L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_float}@ 201711L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_is_always_lock_free}@ 201603L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_lock_free_type_aliases}@ 201907L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_ref}@ 201806L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_atomic_shared_ptr}@ 201711L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_value_initialization}@ 201911L // also in \libheader{atomic}, \libheader{memory} #define @\defnlibxname{cpp_lib_atomic_wait}@ 201907L // also in \libheader{atomic} #define @\defnlibxname{cpp_lib_barrier}@ 202302L // also in \libheader{barrier} #define @\defnlibxname{cpp_lib_bind_back}@ 202202L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_bind_front}@ 201907L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_bit_cast}@ 201806L // also in \libheader{bit} #define @\defnlibxname{cpp_lib_bitops}@ 201907L // also in \libheader{bit} #define @\defnlibxname{cpp_lib_bool_constant}@ 201505L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_bounded_array_traits}@ 201902L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_boyer_moore_searcher}@ 201603L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_byte}@ 201603L // also in \libheader{cstddef} #define @\defnlibxname{cpp_lib_byteswap}@ 202110L // also in \libheader{bit} #define @\defnlibxname{cpp_lib_char8_t}@ 201907L // also in \libheader{atomic}, \libheader{filesystem}, \libheader{istream}, \libheader{limits}, \libheader{locale}, \libheader{ostream}, \libheader{string}, \libheader{string_view} #define @\defnlibxname{cpp_lib_chrono}@ 201907L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_chrono_udls}@ 201304L // also in \libheader{chrono} #define @\defnlibxname{cpp_lib_clamp}@ 201603L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_common_reference}@ 202302L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_common_reference_wrapper}@ 202302L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_concepts}@ 202207L // also in \libheader{concepts}, \libheader{compare} #define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm}, \libheader{utility} #define @\defnlibxname{cpp_lib_constexpr_bitset}@ 202207L // also in \libheader{bitset} #define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202202L // also in \libheader{cmath}, \libheader{cstdlib} #define @\defnlibxname{cpp_lib_constexpr_complex}@ 201711L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_constexpr_dynamic_alloc}@ 201907L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_constexpr_functional}@ 201907L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_constexpr_iterator}@ 201811L // also in \libheader{iterator} #define @\defnlibxname{cpp_lib_constexpr_memory}@ 202202L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_constexpr_numeric}@ 201911L // also in \libheader{numeric} #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 // also in \libheader{tuple} #define @\defnlibxname{cpp_lib_constexpr_typeinfo}@ 202106L // also in \libheader{typeinfo} #define @\defnlibxname{cpp_lib_constexpr_utility}@ 201811L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_constexpr_vector}@ 201907L // also in \libheader{vector} #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_coroutine}@ 201902L // also in \libheader{coroutine} #define @\defnlibxname{cpp_lib_destroying_delete}@ 201806L // also in \libheader{new} #define @\defnlibxname{cpp_lib_enable_shared_from_this}@ 201603L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_endian}@ 201907L // 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_exchange_function}@ 201304L // 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}@ 202207L // also in \libheader{flat_map} #define @\defnlibxname{cpp_lib_flat_set}@ 202207L // also in \libheader{flat_set} #define @\defnlibxname{cpp_lib_format}@ 202207L // also in \libheader{format} #define @\defnlibxname{cpp_lib_format_ranges}@ 202207L // also in \libheader{format} #define @\defnlibxname{cpp_lib_formatters}@ 202302L // also in \libheader{stacktrace}, \libheader{thread} #define @\defnlibxname{cpp_lib_forward_like}@ 202207L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // 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 // also in \libheader{new} #define @\defnlibxname{cpp_lib_has_unique_object_representations}@ 201606L // also in \libheader{type_traits} #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_int_pow2}@ 202002L // also in \libheader{bit} #define @\defnlibxname{cpp_lib_integer_comparison_functions}@ 202002L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_integer_sequence}@ 201304L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_integral_constant_callable}@ 201304L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_interpolate}@ 201902L // also in \libheader{cmath}, \libheader{numeric} #define @\defnlibxname{cpp_lib_invoke}@ 201411L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_invoke_r}@ 202106L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_ios_noreplace}@ 202207L // also in \libheader{ios} #define @\defnlibxname{cpp_lib_is_aggregate}@ 201703L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_constant_evaluated}@ 201811L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_final}@ 201402L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_implicit_lifetime}@ 202302L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_invocable}@ 201703L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_layout_compatible}@ 201907L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_nothrow_convertible}@ 201806L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_null_pointer}@ 201309L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_pointer_interconvertible}@ 201907L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_scoped_enum}@ 202011L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_is_swappable}@ 201603L // 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 // also in \libheader{new} #define @\defnlibxname{cpp_lib_list_remove_return_type}@ 201806L // also in \libheader{forward_list}, \libheader{list} #define @\defnlibxname{cpp_lib_logical_traits}@ 201510L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_make_from_tuple}@ 201606L // also in \libheader{tuple} #define @\defnlibxname{cpp_lib_make_reverse_iterator}@ 201402L // 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}@ 202207L // also in \libheader{mdspan} #define @\defnlibxname{cpp_lib_memory_resource}@ 201603L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_modules}@ 202207L #define @\defnlibxname{cpp_lib_move_iterator_concept}@ 202207L // 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 // 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}@ 201603L // also in \libheader{functional} #define @\defnlibxname{cpp_lib_null_iterators}@ 201304L // also in \libheader{iterator} #define @\defnlibxname{cpp_lib_optional}@ 202110L // also in \libheader{optional} #define @\defnlibxname{cpp_lib_out_ptr}@ 202106L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric} #define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource} #define @\defnlibxname{cpp_lib_print}@ 202207L // also in \libheader{print}, \libheader{ostream} #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} #define @\defnlibxname{cpp_lib_ranges}@ 202302L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_const}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_as_rvalue}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_cartesian_product}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_chunk_by}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_contains}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_enumerate}@ 202302L // also in \libheader{ranges}, \libheader{version} #define @\defnlibxname{cpp_lib_ranges_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_fold}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_ranges_join_with}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_repeat}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_slide}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_ranges_stride}@ 202207L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges} #define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility} #define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_reference_from_temporary}@ 202202L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_remove_cvref}@ 201711L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_result_of_sfinae}@ 201210L // also in \libheader{functional}, \libheader{type_traits} #define @\defnlibxname{cpp_lib_robust_nonmodifying_seq_ops}@ 201304L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_sample}@ 201603L // also in \libheader{algorithm} #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_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_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_source_location}@ 201907L // also in \libheader{source_location} #define @\defnlibxname{cpp_lib_span}@ 202002L // also in \libheader{span} #define @\defnlibxname{cpp_lib_spanstream}@ 202106L // also in \libheader{spanstream} #define @\defnlibxname{cpp_lib_ssize}@ 201902L // also in \libheader{iterator} #define @\defnlibxname{cpp_lib_stacktrace}@ 202011L // also in \libheader{stacktrace} #define @\defnlibxname{cpp_lib_start_lifetime_as}@ 202207L // 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_udls}@ 201304L // also in \libheader{string} #define @\defnlibxname{cpp_lib_string_view}@ 201803L // also in \libheader{string}, \libheader{string_view} #define @\defnlibxname{cpp_lib_syncbuf}@ 201803L // also in \libheader{syncstream} #define @\defnlibxname{cpp_lib_three_way_comparison}@ 201907L // also in \libheader{compare} #define @\defnlibxname{cpp_lib_to_address}@ 201711L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_to_array}@ 201907L // also in \libheader{array} #define @\defnlibxname{cpp_lib_to_chars}@ 201611L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_to_underlying}@ 202102L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_transformation_trait_aliases}@ 201304L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_transparent_operators}@ 201510L // also in \libheader{memory}, \libheader{functional} #define @\defnlibxname{cpp_lib_tuple_like}@ 202207L // also in \libheader{utility}, \libheader{tuple}, \libheader{map}, \libheader{unordered_map} #define @\defnlibxname{cpp_lib_tuple_element_t}@ 201402L // also in \libheader{tuple} #define @\defnlibxname{cpp_lib_tuples_by_type}@ 201304L // also in \libheader{utility}, \libheader{tuple} #define @\defnlibxname{cpp_lib_type_identity}@ 201806L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_type_trait_variable_templates}@ 201510L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_uncaught_exceptions}@ 201411L // also in \libheader{exception} #define @\defnlibxname{cpp_lib_unordered_map_try_emplace}@ 201411L // also in \libheader{unordered_map} #define @\defnlibxname{cpp_lib_unreachable}@ 202202L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_unwrap_ref}@ 201811L // also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_variant}@ 202106L // also in \libheader{variant} #define @\defnlibxname{cpp_lib_void_t}@ 201411L // also in \libheader{type_traits} \end{codeblock} \rSec2[limits.syn]{Header \tcode{} 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 numeric_limits; template class numeric_limits; template class numeric_limits; template class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; template<> class numeric_limits; } \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 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}\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 mantissa. \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. \begin{footnote} Rounding error is described in LIA-1 Section 5.2.4 and Annex C Rationale Section C.5.2.4 --- Rounding and rounding constants. \end{footnote} \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''. \begin{footnote} Required by LIA-1. \end{footnote} \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''. \begin{footnote} Required by LIA-1. \end{footnote} \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. \begin{footnote} Required by LIA-1. \end{footnote} \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. \begin{footnote} Required by LIA-1. \end{footnote} \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. \begin{footnote} Required by LIA-1. \end{footnote} \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. \begin{footnote} Required by LIA-1. \end{footnote} 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 ISO/IEC/IEEE 60559. \begin{footnote} ISO/IEC/IEEE 60559: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{footnote} Required by LIA-1. \end{footnote} \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. \begin{footnote} Required by LIA-1. \end{footnote} 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. \begin{footnote} Required by LIA-1. \end{footnote} \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 ISO/IEC/IEEE 60559. Required by LIA-1. \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}. Required by LIA-1. \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 { 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}% \begin{codeblock} namespace std { template<> class numeric_limits { 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{} synopsis} \indexheader{climits}% \indexlibraryglobal{CHAR_BIT}% \indexlibraryglobal{SCHAR_MIN}% \indexlibraryglobal{SCHAR_MAX}% \indexlibraryglobal{UCHAR_MAX}% \indexlibraryglobal{CHAR_MIN}% \indexlibraryglobal{CHAR_MAX}% \indexlibraryglobal{MB_LEN_MAX}% \indexlibraryglobal{SHRT_MIN}% \indexlibraryglobal{SHRT_MAX}% \indexlibraryglobal{USHRT_MAX}% \indexlibraryglobal{INT_MIN}% \indexlibraryglobal{INT_MAX}% \indexlibraryglobal{UINT_MAX}% \indexlibraryglobal{LONG_MIN}% \indexlibraryglobal{LONG_MAX}% \indexlibraryglobal{ULONG_MAX}% \indexlibraryglobal{LLONG_MIN}% \indexlibraryglobal{LLONG_MAX}% \indexlibraryglobal{ULLONG_MAX}% \begin{codeblock} // all freestanding #define CHAR_BIT @\seebelow@ #define SCHAR_MIN @\seebelow@ #define SCHAR_MAX @\seebelow@ #define UCHAR_MAX @\seebelow@ #define CHAR_MIN @\seebelow@ #define CHAR_MAX @\seebelow@ #define MB_LEN_MAX @\seebelow@ #define SHRT_MIN @\seebelow@ #define SHRT_MAX @\seebelow@ #define USHRT_MAX @\seebelow@ #define INT_MIN @\seebelow@ #define INT_MAX @\seebelow@ #define UINT_MAX @\seebelow@ #define LONG_MIN @\seebelow@ #define LONG_MAX @\seebelow@ #define ULONG_MAX @\seebelow@ #define LLONG_MIN @\seebelow@ #define LLONG_MAX @\seebelow@ #define ULLONG_MAX @\seebelow@ \end{codeblock} \pnum The header \libheader{climits} defines all macros the same as the C standard library header \libheader{limits.h}. \begin{note} Except for \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.2.4.2.1} \rSec2[cfloat.syn]{Header \tcode{} synopsis} \indexheader{cfloat}% \indexlibraryglobal{DBL_DECIMAL_DIG}% \indexlibraryglobal{DBL_DIG}% \indexlibraryglobal{DBL_EPSILON}% \indexlibraryglobal{DBL_HAS_SUBNORM}% \indexlibraryglobal{DBL_MANT_DIG}% \indexlibraryglobal{DBL_MAX}% \indexlibraryglobal{DBL_MAX_10_EXP}% \indexlibraryglobal{DBL_MAX_EXP}% \indexlibraryglobal{DBL_MIN}% \indexlibraryglobal{DBL_MIN_10_EXP}% \indexlibraryglobal{DBL_MIN_EXP}% \indexlibraryglobal{DBL_TRUE_MIN}% \indexlibraryglobal{DECIMAL_DIG}% \indexlibraryglobal{FLT_DECIMAL_DIG}% \indexlibraryglobal{FLT_DIG}% \indexlibraryglobal{FLT_EPSILON}% \indexlibraryglobal{FLT_EVAL_METHOD}% \indexlibraryglobal{FLT_HAS_SUBNORM}% \indexlibraryglobal{FLT_MANT_DIG}% \indexlibraryglobal{FLT_MAX}% \indexlibraryglobal{FLT_MAX_10_EXP}% \indexlibraryglobal{FLT_MAX_EXP}% \indexlibraryglobal{FLT_MIN}% \indexlibraryglobal{FLT_MIN_10_EXP}% \indexlibraryglobal{FLT_MIN_EXP}% \indexlibraryglobal{FLT_RADIX}% \indexlibraryglobal{FLT_ROUNDS}% \indexlibraryglobal{FLT_TRUE_MIN}% \indexlibraryglobal{LDBL_DECIMAL_DIG}% \indexlibraryglobal{LDBL_DIG}% \indexlibraryglobal{LDBL_EPSILON}% \indexlibraryglobal{LDBL_HAS_SUBNORM}% \indexlibraryglobal{LDBL_MANT_DIG}% \indexlibraryglobal{LDBL_MAX}% \indexlibraryglobal{LDBL_MAX_10_EXP}% \indexlibraryglobal{LDBL_MAX_EXP}% \indexlibraryglobal{LDBL_MIN}% \indexlibraryglobal{LDBL_MIN_10_EXP}% \indexlibraryglobal{LDBL_MIN_EXP}% \indexlibraryglobal{LDBL_TRUE_MIN}% \begin{codeblock} // all freestanding #define FLT_ROUNDS @\seebelow@ #define FLT_EVAL_METHOD @\seebelow@ #define FLT_HAS_SUBNORM @\seebelow@ #define DBL_HAS_SUBNORM @\seebelow@ #define LDBL_HAS_SUBNORM @\seebelow@ #define FLT_RADIX @\seebelow@ #define FLT_MANT_DIG @\seebelow@ #define DBL_MANT_DIG @\seebelow@ #define LDBL_MANT_DIG @\seebelow@ #define FLT_DECIMAL_DIG @\seebelow@ #define DBL_DECIMAL_DIG @\seebelow@ #define LDBL_DECIMAL_DIG @\seebelow@ #define DECIMAL_DIG @\seebelow@ #define FLT_DIG @\seebelow@ #define DBL_DIG @\seebelow@ #define LDBL_DIG @\seebelow@ #define FLT_MIN_EXP @\seebelow@ #define DBL_MIN_EXP @\seebelow@ #define LDBL_MIN_EXP @\seebelow@ #define FLT_MIN_10_EXP @\seebelow@ #define DBL_MIN_10_EXP @\seebelow@ #define LDBL_MIN_10_EXP @\seebelow@ #define FLT_MAX_EXP @\seebelow@ #define DBL_MAX_EXP @\seebelow@ #define LDBL_MAX_EXP @\seebelow@ #define FLT_MAX_10_EXP @\seebelow@ #define DBL_MAX_10_EXP @\seebelow@ #define LDBL_MAX_10_EXP @\seebelow@ #define FLT_MAX @\seebelow@ #define DBL_MAX @\seebelow@ #define LDBL_MAX @\seebelow@ #define FLT_EPSILON @\seebelow@ #define DBL_EPSILON @\seebelow@ #define LDBL_EPSILON @\seebelow@ #define FLT_MIN @\seebelow@ #define DBL_MIN @\seebelow@ #define LDBL_MIN @\seebelow@ #define FLT_TRUE_MIN @\seebelow@ #define DBL_TRUE_MIN @\seebelow@ #define 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.2.4.2.2} \rSec1[support.arith.types]{Arithmetic types} \rSec2[cstdint.syn]{Header \tcode{} 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}% \begin{codeblock} // all freestanding 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_FAST@\placeholdernc{N}@_MIN @\seebelow@ #define INT_FAST@\placeholdernc{N}@_MAX @\seebelow@ #define UINT_FAST@\placeholdernc{N}@_MAX @\seebelow@ #define INT_LEAST@\placeholdernc{N}@_MIN @\seebelow@ #define INT_LEAST@\placeholdernc{N}@_MAX @\seebelow@ #define UINT_LEAST@\placeholdernc{N}@_MAX @\seebelow@ #define INTMAX_MIN @\seebelow@ #define INTMAX_MAX @\seebelow@ #define UINTMAX_MAX @\seebelow@ #define INTPTR_MIN @\seebelow@ // optional #define INTPTR_MAX @\seebelow@ // optional #define UINTPTR_MAX @\seebelow@ // optional #define PTRDIFF_MIN @\seebelow@ #define PTRDIFF_MAX @\seebelow@ #define SIZE_MAX @\seebelow@ #define SIG_ATOMIC_MIN @\seebelow@ #define SIG_ATOMIC_MAX @\seebelow@ #define WCHAR_MIN @\seebelow@ #define WCHAR_MAX @\seebelow@ #define WINT_MIN @\seebelow@ #define WINT_MAX @\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}. \xrefc{7.20} \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 defines the corresponding \grammarterm{typedef-name}s. Each of the macros listed in this subclause is defined if and only if the implementation defines 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{} synopsis} \pnum The header \libheader{stdfloat} defines type aliases for the optional extended floating-point types that are specified in \ref{basic.extended.fp}. \indexheader{stdfloat}% \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 of 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.22.4} \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{} 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 [[nodiscard]] 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 [[nodiscard]] void* operator new(std::size_t size); [[nodiscard]] void* operator new(std::size_t size, std::align_val_t alignment); [[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) noexcept; [[nodiscard]] 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; [[nodiscard]] void* operator new[](std::size_t size); [[nodiscard]] void* operator new[](std::size_t size, std::align_val_t alignment); [[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; [[nodiscard]] 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; [[nodiscard]] void* operator new (std::size_t size, void* ptr) noexcept; [[nodiscard]] 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. \newcommand{\replaceabledesc}[1]{% A \Cpp{} program may define functions with #1 of these function signatures, and thereby displace the default versions defined by the \Cpp{} standard library.% } \rSec3[new.delete.single]{Single-object forms} \indexlibrarymember{new}{operator}% \begin{itemdecl} [[nodiscard]] void* operator new(std::size_t size); [[nodiscard]] 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 \replaceable \replaceabledesc{either} \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} \end{itemdescr} \indexlibrarymember{new}{operator}% \begin{itemdecl} [[nodiscard]] void* operator new(std::size_t size, const std::nothrow_t&) noexcept; [[nodiscard]] 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 \replaceable \replaceabledesc{either} \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} \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 \replaceable \replaceabledesc{any} If a function without a \tcode{size} parameter is defined, the program should also define the corresponding function with a \tcode{size} parameter. If a function with a \tcode{size} parameter is defined, the program shall also define the corresponding version without the \tcode{size} parameter. \begin{note} The default behavior below might change in the future, which will require replacing both deallocation functions when replacing the allocation function. \end{note} \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 above \replaceable 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}. \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 \replaceable \replaceabledesc{either} \pnum \default Calls \tcode{operator delete(ptr)}, or \tcode{operator delete(ptr, alignment)}, respectively. \end{itemdescr} \rSec3[new.delete.array]{Array forms} \indexlibrarymember{new}{operator}% \begin{itemdecl} [[nodiscard]] void* operator new[](std::size_t size); [[nodiscard]] 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 \replaceable \replaceabledesc{either} \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. \end{itemdescr} \indexlibrarymember{new}{operator}% \begin{itemdecl} [[nodiscard]] void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; [[nodiscard]] 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 \replaceable \replaceabledesc{either} \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. \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 \replaceable \replaceabledesc{any} If a function without a \tcode{size} parameter is defined, the program should also define the corresponding function with a \tcode{size} parameter. If a function with a \tcode{size} parameter is defined, the program shall also define the corresponding version without the \tcode{size} parameter. \begin{note} The default behavior below might change in the future, which will require replacing both deallocation functions when replacing the allocation function. \end{note} \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. \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 \replaceable \replaceabledesc{either} \pnum \default Calls \tcode{operator delete[](ptr)}, or \tcode{operator delete[](ptr, alignment)}, respectively. \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} [[nodiscard]] 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} [[nodiscard]] 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 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} 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 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} 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 [[nodiscard]] constexpr T* launder(T* p) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \mandates \tcode{!is_function_v \&\& !is_void_v} 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(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 cat; alignas(hardware_destructive_interference_size) atomic 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 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 \libheaderdef{typeinfo} defines a type associated with type information generated by the implementation. It also defines two types for reporting dynamic type identification errors. \rSec2[typeinfo.syn]{Header \tcode{} synopsis} \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; // cannot be copied type_info& operator=(const type_info&) = delete; // cannot be copied }; } \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 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} 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 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} const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum \returns An \impldef{return value of \tcode{bad_typeid::what}} \ntbs{}. \end{itemdescr} \rSec1[support.srcloc]{Source location} \rSec2[source.location.syn]{Header \tcode{} 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} \item \tcode{is_nothrow_move_assignable_v} \item \tcode{is_nothrow_swappable_v} \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}, 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{} 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; int uncaught_exceptions() noexcept; using exception_ptr = @\unspec@; exception_ptr current_exception() noexcept; [[noreturn]] void rethrow_exception(exception_ptr p); template exception_ptr make_exception_ptr(E e) noexcept; template [[noreturn]] void throw_with_nested(T&& t); template 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: exception() noexcept; exception(const exception&) noexcept; exception& operator=(const exception&) noexcept; virtual ~exception(); 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 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} exception(const exception& rhs) noexcept; 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} virtual ~exception(); \end{itemdecl} \begin{itemdescr} \pnum \effects Destroys an object of class \tcode{exception}. \end{itemdescr} \indexlibrarymember{what}{exception}% \begin{itemdecl} virtual const char* what() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An \impldef{return value of \tcode{exception::what}} \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}. 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 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} 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} int uncaught_exceptions() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The number of uncaught exceptions\iref{except.uncaught}. \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} 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} \end{itemdescr} \indexlibraryglobal{current_exception}% \begin{itemdecl} 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 is allowed to substitute a \tcode{bad_exception} object to avoid infinite recursion. \end{note} \end{itemdescr} \indexlibraryglobal{rethrow_exception}% \begin{itemdecl} [[noreturn]] 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 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} \rSec2[except.nested]{\tcode{nested_exception}} \indexlibraryglobal{nested_exception}% \begin{codeblock} namespace std { class nested_exception { public: nested_exception() noexcept; nested_exception(const nested_exception&) noexcept = default; nested_exception& operator=(const nested_exception&) noexcept = default; virtual ~nested_exception() = default; // access functions [[noreturn]] void rethrow_nested() const; exception_ptr nested_ptr() const noexcept; }; template [[noreturn]] void throw_with_nested(T&& t); template 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} 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]] 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} 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 [[noreturn]] void throw_with_nested(T&& t); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{U} be \tcode{decay_t}. \pnum \expects \tcode{U} meets the \oldconcept{CopyConstructible} requirements. \pnum \throws If \tcode{is_class_v \&\& !is_final_v \&\& !is_base_of_v} 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)}, otherwise \tcode{std::forward(t)}. \end{itemdescr} \indexlibrarymember{rethrow_if_nested}{nested_exception}% \begin{itemdecl} template 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(addressof(e))) p->rethrow_nested(); \end{codeblock} \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{} synopsis} \indexlibraryglobal{initializer_list}% \indexlibraryglobal{begin}% \indexlibraryglobal{end}% \begin{codeblock} // all freestanding namespace std { template 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 size_t size() const noexcept; // number of elements constexpr const E* begin() const noexcept; // first element constexpr const E* end() const noexcept; // one past the last element }; // \ref{support.initlist.range}, initializer list range access template constexpr const E* begin(initializer_list il) noexcept; template constexpr const E* end(initializer_list il) noexcept; } \end{codeblock} \pnum An object of type \tcode{initializer_list} 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 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{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 time. \end{itemdescr} \rSec2[support.initlist.range]{Initializer list range access} \indexlibrary{\idxcode{begin(initializer_list)}}% \begin{itemdecl} template constexpr const E* begin(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{il.begin()}. \end{itemdescr} \indexlibrary{\idxcode{end(initializer_list)}}% \begin{itemdecl} template constexpr const E* end(initializer_list il) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{il.end()}. \end{itemdescr} \rSec1[cmp]{Comparisons} \rSec2[compare.syn]{Header \tcode{} 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}% \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 struct common_comparison_category { using type = @\seebelow@; }; template using common_comparison_category_t = typename common_comparison_category::type; // \ref{cmp.concept}, concept \libconcept{three_way_comparable} template concept three_way_comparable = @\seebelow@; template concept three_way_comparable_with = @\seebelow@; // \ref{cmp.result}, result of three-way comparison template struct compare_three_way_result; template using compare_three_way_result_t = typename compare_three_way_result::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@; } } \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 subclause \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 value; // \expos bool is_ordered; // \expos // exposition-only constructors constexpr explicit partial_ordering(@\placeholder{ord}@ v) noexcept : value(int(v)), is_ordered(true) {} // \expos constexpr explicit partial_ordering(@\placeholder{ncmp}@ v) noexcept : value(int(v)), 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.is_ordered \&\& v.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.is_ordered \&\& 0 @ v.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 value; // \expos // exposition-only constructors constexpr explicit weak_ordering(@\placeholder{ord}@ v) noexcept : 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} value == 0 ? partial_ordering::equivalent : 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.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.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 value; // \expos // exposition-only constructors constexpr explicit strong_ordering(@\placeholder{ord}@ v) noexcept : 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} value == 0 ? partial_ordering::equivalent : 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} value == 0 ? weak_ordering::equivalent : 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.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.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 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 concept @\defexposconcept{compares-as}@ = // \expos @\libconcept{same_as}@, Cat>; template concept @\defexposconcept{partially-ordered-with}@ = // \expos requires(const remove_reference_t& t, const remove_reference_t& 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} and \tcode{const remove_reference_t}, respectively. \tcode{T} and \tcode{U} model \tcode{\exposconcept{partially-ordered-with}} 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 concept @\deflibconcept{three_way_comparable}@ = @\exposconcept{weakly-equality-comparable-with}@ && @\exposconcept{partially-ordered-with}@ && requires(const remove_reference_t& a, const remove_reference_t& b) { { a <=> b } -> @\exposconcept{compares-as}@; }; \end{codeblock} \pnum Let \tcode{a} and \tcode{b} be lvalues of type \tcode{const remove_reference_t}. \tcode{T} and \tcode{Cat} model \tcode{\libconcept{three_way_comparable}} 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 concept @\deflibconcept{three_way_comparable_with}@ = @\libconcept{three_way_comparable}@ && @\libconcept{three_way_comparable}@ && @\exposconcept{comparison-common-type-with}@ && @\libconcept{three_way_comparable}@< common_reference_t&, const remove_reference_t&>, Cat> && @\exposconcept{weakly-equality-comparable-with}@ && @\exposconcept{partially-ordered-with}@ && requires(const remove_reference_t& t, const remove_reference_t& u) { { t <=> u } -> @\exposconcept{compares-as}@; { u <=> t } -> @\exposconcept{compares-as}@; }; \end{codeblock} \pnum Let \tcode{t} and \tcode{t2} be lvalues denoting distinct equal objects of types \tcode{const remove_reference_t} and \tcode{remove_cvref_t}, respectively, and let \tcode{u} and \tcode{u2} be lvalues denoting distinct equal objects of types \tcode{const remove_reference_t} and \tcode{remove_cvref_t}, respectively. Let \tcode{C} be \tcode{common_reference_t\&, const remove_reference_t\&>}. Let \tcode{\exposid{CONVERT_TO_LVALUE}(E)} be defined as in \ref{concepts.compare.general}. \tcode{T}, \tcode{U}, and \tcode{Cat} model \tcode{\libconcept{three_way_comparable_with}} 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}(t2) <=> \exposid{CONVERT_TO_LVALUE}(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}}\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} and \tcode{const remove_reference_t}, 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::is_iec559} is \tcode{true}, is additionally consistent with the \tcode{totalOrder} operation as specified in ISO/IEC/IEEE 60559. \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::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)} and \tcode{decltype(E < F)} 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} \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{} synopsis} \indexheader{coroutine}% \indexlibraryglobal{noop_coroutine_handle}% \begin{codeblock} // all freestanding #include // see \ref{compare.syn} namespace std { // \ref{coroutine.traits}, coroutine traits template struct coroutine_traits; // \ref{coroutine.handle}, coroutine handle template 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 struct hash; template struct hash>; // \ref{coroutine.noop}, no-op coroutines struct noop_coroutine_promise; template<> struct coroutine_handle; using noop_coroutine_handle = coroutine_handle; 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}} \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} has the following publicly accessible member: \begin{codeblock} using promise_type = typename R::promise_type; \end{codeblock} Otherwise, \tcode{coroutine_traits} 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 { // \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 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} 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 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 of type \cv{}~\tcode{coroutine_handle}. \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 struct hash>; \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}} \indexlibraryglobal{coroutine_handle}% \begin{codeblock} namespace std { template<> struct coroutine_handle { // \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}% \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}% \begin{itemdecl} constexpr explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true}. \end{itemdescr} \indexlibrarymember{done}{coroutine_handle}% \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}% \indexlibrarymember{resume}{coroutine_handle}% \indexlibrarymember{destroy}{coroutine_handle}% \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}% \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}% \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{} synopsis} \indexheader{cstdarg}% \indexlibraryglobal{va_list}% \indexlibraryglobal{va_start}% \indexlibraryglobal{va_copy}% \indexlibraryglobal{va_end}% \indexlibraryglobal{va_arg}% \begin{codeblock} // all freestanding namespace std { using va_list = @\seebelow@; } #define va_arg(V, P) @\seebelow@ #define va_copy(VDST, VSRC) @\seebelow@ #define va_end(V) @\seebelow@ #define va_start(V, P) @\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 ISO C 6.5.2.2, the definition in~\ref{expr.call} applies. \item The restrictions that ISO C places on the second parameter to the \indexlibraryglobal{va_start}% \tcode{va_start} macro in header \libheader{stdarg.h} are different in this document. The parameter \tcode{parmN} is the rightmost parameter in the variable parameter list of the function definition (the one just before the \tcode{...}). \begin{footnote} Note that \tcode{va_start} is required to work as specified even if unary \tcode{operator\&} is overloaded for the type of \tcode{parmN}. \end{footnote} If the parameter \tcode{parmN} is a pack expansion\iref{temp.variadic} or an entity resulting from a lambda capture\iref{expr.prim.lambda}, the program is ill-formed, no diagnostic required. If the parameter \tcode{parmN} is of a reference type, or of a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined. \end{itemize} \xrefc{7.16.1.1} \rSec2[csetjmp.syn]{Header \tcode{} synopsis} \indexlibraryglobal{jmp_buf}% \indexlibraryglobal{longjmp}% \indexlibraryglobal{setjmp}% \begin{codeblock} 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{} 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 ISO C. Source files that are not intended to also be valid ISO 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{} 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 ISO 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 // for \tcode{bool} in C, no effect in \Cpp{} #include // for \tcode{size_t} #ifdef __cplusplus // see \ref{cpp.predefined} extern "C" // see \ref{dcl.link} #endif void f(bool b[], 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{stdbool.h} \\ \libheaderdef{stddef.h} \\ \columnbreak \libheaderdef{stdint.h} \\ \libheaderdef{stdio.h} \\ \libheaderdef{stdlib.h} \\ \libheaderdef{string.h} \\ \libheader{tgmath.h} \\ \libheaderdef{time.h} \\ \columnbreak \libheaderdef{uchar.h} \\ \libheaderdef{wchar.h} \\ \libheaderdef{wctype.h} \\ \end{multicolfloattable} \rSec2[complex.h.syn]{Header \tcode{} synopsis} \indexheader{complex.h}% \begin{codeblock} #include \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{} 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{} 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}, with the following changes: The header \libheader{stdalign.h} does not define a macro named \tcode{alignas}. \xrefc{7.15} \rSec2[stdbool.h.syn]{Header \tcode{} synopsis} \indexheader{stdbool.h}% \indexhdr{stdbool.h}% \pnum The contents of the \Cpp{} header \libheader{stdbool.h} are the same as the C standard library header \libheader{stdbool.h}, with the following changes: The header \libheader{stdbool.h} does not define macros named \tcode{bool}, \tcode{true}, or \tcode{false}. \xrefc{7.18} \rSec2[tgmath.h.syn]{Header \tcode{} synopsis} \indexheader{tgmath.h}% \begin{codeblock} #include #include \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{stdbool.h}, and \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{} 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 the C Standard. It may also provide these names within the namespace \tcode{std}. \end{example}