diff --git a/source/back.tex b/source/back.tex index 0314b1007c..60a20e7d51 100644 --- a/source/back.tex +++ b/source/back.tex @@ -13,8 +13,10 @@ \chapter{Bibliography} \doccite{Information technology --- Language independent arithmetic --- Part 1: Integer and floating point arithmetic} \item - ISO/IEC/IEEE 60559:2011, \doccite{Information technology --- - Microprocessor Systems --- Floating-Point arithmetic} + ISO/IEC TS 18661-3:2015, + \doccite{Information Technology --- + Programming languages, their environments, and system software interfaces --- + Floating-point extensions for C --- Part 3: Interchange and extended types} % Other international standards. \item %%% Format for the following entry is based on that specified at diff --git a/source/basic.tex b/source/basic.tex index 582f7bb2c4..b02fcbf3da 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4995,15 +4995,23 @@ The types \keyword{float}, \keyword{double}, and \tcode{\keyword{long} \keyword{double}}, and cv-qualified versions\iref{basic.type.qualifier} thereof, +are collectively termed +\defnx{standard floating-point types}{type!floating-point!standard}. +An implementation may also provide additional types +that represent floating-point values and define them (and cv-qualified versions thereof) to be +\defnx{extended floating-point types}{type!floating-point!extended}. +The standard and extended floating-point types are collectively termed \defnx{floating-point types}{type!floating-point}. -The value -representation of floating-point types is \impldef{value representation of -floating-point types}. -\indextext{floating-point type!implementation-defined}% \begin{note} -This document imposes no requirements on the accuracy of -floating-point operations; see also~\ref{support.limits}. +Any additional implementation-specific types representing floating-point values +that are not defined by the implementation to be extended floating-point types +are not considered to be floating-point types, and +this document imposes no requirements on them or +their interactions with floating-point types. \end{note} +Except as specified in \ref{basic.extended.fp}, +the object and value representations and accuracy of operations +of floating-point types is \impldef{representation of floating-point types}. \pnum Integral and floating-point types are collectively @@ -5049,6 +5057,90 @@ same value representation, they are nevertheless different types. \end{note} +\rSec2[basic.extended.fp]{Optional extended floating-point types} + +\pnum +If the implementation supports an extended floating-point type\iref{basic.fundamental} +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary16, +then the \grammarterm{typedef-name} \tcode{std::float16_t} +is defined in the header \libheaderref{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT16_T} is defined\iref{cpp.predefined}, and +the floating-point literal suffixes \tcode{f16} and \tcode{F16} +are supported\iref{lex.fcon}. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary32, +then the \grammarterm{typedef-name} \tcode{std::float32_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT32_T} is defined, and +the floating-point literal suffixes \tcode{f32} and \tcode{F32} are supported. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary64, +then the \grammarterm{typedef-name} \tcode{std::float64_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT64_T} is defined, and +the floating-point literal suffixes \tcode{f64} and \tcode{F64} are supported. + +\pnum +If the implementation supports an extended floating-point type +whose properties are specified by +the ISO/IEC/IEEE 60559 floating-point interchange format binary128, +then the \grammarterm{typedef-name} \tcode{std::float128_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_FLOAT128_T} is defined, and +the floating-point literal suffixes \tcode{f128} and \tcode{F128} are supported. + +\pnum +If the implementation supports an extended floating-point type +with the properties, as specified by ISO/IEC/IEEE 60559, of +radix ($b$) of 2, +storage width in bits ($k$) of 16, +precision in bits ($p$) of 8, +maximum exponent ($emax$) of 127, and +exponent field width in bits ($w$) of 8, then +the \grammarterm{typedef-name} \tcode{std::bfloat16_t} +is defined in the header \libheader{stdfloat} and names such a type, +the macro \mname{STDCPP_BFLOAT16_T} is defined, and +the floating-point literal suffixes \tcode{bf16} and \tcode{BF16} are supported. + +\pnum +\begin{note} +A summary of the parameters for each type is given in \tref{basic.extended.fp}. +The precision $p$ includes the implicit 1 bit at the beginning of the mantissa, +so the storage used for the mantissa is $p-1$ bits. +ISO/IEC/IEEE 60559 does not assign a name for a type +having the parameters specified for \tcode{std::bfloat16_t}. +\end{note} +\begin{floattable} +{Properties of named extended floating-point types}{basic.extended.fp}{llllll} +\topline +\lhdr{Parameter} & \chdr{\tcode{float16_t}} & \chdr{\tcode{float32_t}} & +\chdr{\tcode{float64_t}} & \chdr{\tcode{float128_t}} & +\rhdr{\tcode{bfloat16_t}} \\ +\capsep +ISO/IEC/IEEE 60559 name & binary16 & binary32 & binary64 & binary128 & \\ +$k$, storage width in bits & 16 & 32 & 64 & 128 & 16 \\ +$p$, precision in bits & 11 & 24 & 53 & 113 & 8 \\ +$emax$, maximum exponent & 15 & 127 & 1023 & 16383 & 127 \\ +$w$, exponent field width in bits & 5 & 8 & 11 & 15 & 8 \\ +\end{floattable} + +\pnum +\recommended +Any names that the implementation provides for +the extended floating-point types described in this subsection +that are in addition to the names defined in the \libheader{stdfloat} header +should be chosen to increase compatibility and interoperability +with the interchange types +\tcode{_Float16}, \tcode{_Float32}, \tcode{_Float64}, and \tcode{_Float128} +defined in ISO/IEC TS 18661-3 and with future versions of the C standard. + \rSec2[basic.compound]{Compound types} \pnum @@ -5337,7 +5429,7 @@ has the top-level cv-qualifier \keyword{volatile}. \end{example} -\rSec2[conv.rank]{Integer conversion rank}% +\rSec2[conv.rank]{Conversion ranks}% \indextext{conversion!integer rank} \pnum @@ -5394,6 +5486,57 @@ conversions\iref{expr.arith.conv}. \end{note} +\pnum +Every floating-point type has a \defnadj{floating-point}{conversion rank} +defined as follows: +\begin{itemize} +\item +The rank of a floating point type \tcode{T} is greater than +the rank of any floating-point type +whose set of values is a proper subset of the set of values of \tcode{T}. +\item +The rank of \tcode{\keyword{long} \keyword{double}} is greater than +the rank of \keyword{double}, +which is greater than the rank of \keyword{float}. +\item +Two extended floating-point types with the same set of values have equal ranks. +\item +An extended floating-point type with the same set of values as +exactly one cv-unqualified standard floating-point type +has a rank equal to the rank of that standard floating-point type. +\item +An extended floating-point type with the same set of values as +more than one cv-unqualified standard floating-point type +has a rank equal to the rank of \keyword{double}. +\end{itemize} +\begin{note} +The conversion ranks of floating-point types \tcode{T1} and \tcode{T2} +are unordered if the set of values of \tcode{T1} is +neither a subset nor a superset of the set of values of \tcode{T2}. +This can happen when one type has both a larger range and a lower precision +than the other. +\end{note} + +\pnum +Floating-point types that have equal floating-point conversion ranks +are ordered by floating-point conversion subrank. +The subrank forms a total order among types with equal ranks. +The types +\tcode{std::float16_t}, +\tcode{std::float32_t}, +\tcode{std::float64_t}, and +\tcode{std::float128_t}\iref{stdfloat.syn} +have a greater conversion subrank than any standard floating-point type +with equal conversion rank. +Otherwise, the conversion subrank order is +\impldef{floating-point conversion subrank}. + +\pnum +\begin{note} +The floating-point conversion rank and subrank are used in +the definition of the usual arithmetic conversions\iref{expr.arith.conv}. +\end{note} + \rSec1[basic.exec]{Program execution} \rSec2[intro.execution]{Sequential execution} diff --git a/source/declarations.tex b/source/declarations.tex index 27b1fa751a..0b2e7d86b1 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5948,8 +5948,10 @@ \begin{itemize} \item from a floating-point type to an integer type, or -\item from \tcode{long double} to \tcode{double} or \tcode{float}, or from -\tcode{double} to \tcode{float}, except where the source is a constant expression and +\item from a floating-point type \tcode{T} to another floating-point type +whose floating-point conversion rank is neither greater than nor equal to +that of \tcode{T}, +except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or diff --git a/source/expressions.tex b/source/expressions.tex index 04d2da8ce5..71906feade 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -929,7 +929,13 @@ \pnum \indextext{conversion!floating-point}% A prvalue of floating-point type can be converted to a prvalue of -another floating-point type. If the source value can be exactly +another floating-point type +with a greater or equal conversion rank\iref{conv.rank}. +A prvalue of standard floating-point type can be converted to +a prvalue of another standard floating-point type. + +\pnum +If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an @@ -1114,24 +1120,36 @@ \item If either operand is of scoped enumeration type\iref{dcl.enum}, no conversions are performed; if the other operand does not have the same type, the expression is ill-formed. - -\item If either operand is of type \tcode{\keyword{long} \keyword{double}}, the -other shall be converted to \tcode{\keyword{long} \keyword{double}}. - -\item Otherwise, if either operand is \keyword{double}, the other shall be -converted to \keyword{double}. - -\item Otherwise, if either operand is \keyword{float}, the other shall be -converted to \keyword{float}. - -\item Otherwise, the integral promotions\iref{conv.prom} shall be +\item Otherwise, if either operand is of floating-point type, +the following rules are applied: +\begin{itemize} +\item +If both operands have the same type, no further conversion is needed. +\item +Otherwise, if one of the operands is of a non-floating-point type, +that operand is converted to the type of +the operand with the floating-point type. +\item +Otherwise, if the floating-point conversion ranks\iref{conv.rank} of +the types of the operands are ordered but not equal, +then the operand of the type with the lesser floating-point conversion rank +is converted to the type of the other operand. +\item +Otherwise, if the floating-point conversion ranks of the types of +the operands are equal, +then the operand with the lesser floating-point conversion subrank\iref{conv.rank} +is converted to the type of the other operand. +\item +Otherwise, the expression is ill-formed. +\end{itemize} +\item Otherwise, the integral promotions\iref{conv.prom} are performed on both operands. \begin{footnote} As a consequence, operands of type \keyword{bool}, \keyword{char8_t}, \keyword{char16_t}, \keyword{char32_t}, \keyword{wchar_t}, or an enumerated type are converted to some integral type. \end{footnote} -Then the following rules shall be applied to the promoted operands: +Then the following rules are applied to the promoted operands: \begin{itemize} @@ -1140,20 +1158,20 @@ \item Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer -conversion rank shall be converted to the type of the operand with +conversion rank is converted to the type of the operand with greater rank. \item Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the -operand with signed integer type shall be converted to the type of the +operand with signed integer type is converted to the type of the operand with unsigned integer type. \item Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned -integer type, the operand with unsigned integer type shall be converted +integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type. -\item Otherwise, both operands shall be converted to the unsigned +\item Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type. \end{itemize} @@ -4096,6 +4114,17 @@ underlying type of the enumeration\iref{conv.fpint}, and subsequently to the enumeration type. +\pnum +A prvalue of floating-point type can be explicitly converted to +any other floating-point type. +If the source value can be exactly represented in the destination type, +the result of the conversion has that exact representation. +If the source value is between two adjacent destination values, +the result of the conversion is +an \impldef{result of inexact floating-point conversion} choice of +either of those values. +Otherwise, the behavior is undefined. + \pnum \indextext{cast!base class}% \indextext{cast!derived class}% diff --git a/source/intro.tex b/source/intro.tex index 9200f81357..f24ffd011f 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -33,6 +33,7 @@ For undated references, the latest edition of the referenced document (including any amendments) applies. \begin{itemize} +% ISO documents in numerical order. \item ISO/IEC 2382, \doccite{Information technology --- Vocabulary} \item ISO 8601:2004, \doccite{Data elements and interchange formats --- Information interchange --- Representation of dates and times} @@ -58,9 +59,12 @@ \end{footnote} \doccite{Information technology --- Universal Multiple-Octet Coded Character Set (UCS)} +\item ISO/IEC/IEEE 60559:2020, \doccite{Information technology --- +Microprocessor Systems --- Floating-Point arithmetic} \item ISO 80000-2:2009, \doccite{Quantities and units --- Part 2: Mathematical signs and symbols to be used in the natural sciences and technology} +% Other international standards. \item Ecma International, \doccite{ECMAScript \begin{footnote} ECMAScript\textregistered\ is a registered trademark of Ecma diff --git a/source/iostreams.tex b/source/iostreams.tex index 2cd777e276..ac91f6ed3a 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -4216,6 +4216,13 @@ \rSec4[istream.general]{General} +\pnum +When a function is specified +with a type placeholder of \tcode{\placeholder{extended-floating-point-type}}, +the implementation provides overloads +for all cv-unqualified extended floating-point types\iref{basic.fundamental} +in lieu of \tcode{\placeholder{extended-floating-\brk{}point-type}}. + \indexlibraryglobal{basic_istream}% \begin{codeblock} namespace std { @@ -4253,6 +4260,7 @@ basic_istream& operator>>(float& f); basic_istream& operator>>(double& f); basic_istream& operator>>(long double& f); + basic_istream& operator>>(@\placeholder{extended-floating-point-type}@& f); basic_istream& operator>>(void*& p); basic_istream& operator>>(basic_streambuf* sb); @@ -4729,6 +4737,64 @@ \end{codeblock} \end{itemdescr} +\begin{itemdecl} +basic_istream& operator>>(@\placeholder{extended-floating-point-type}@& val); +\end{itemdecl} + +\begin{itemdescr} +\pnum +If +the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is not less than or equal to that of \tcode{long double}, +then an invocation of the operator function is conditionally supported +with \impldef{\tcode{operator>>} for large extended floating-point types} +semantics. + +\pnum +Otherwise, let \tcode{FP} be a standard floating-point type: +\begin{itemize} +\item +if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{float}, +then \tcode{FP} is \tcode{float}, +\item +otherwise, +if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{double}, +then \tcode{FP} is \tcode{double}, +\item +otherwise, \tcode{FP} is \tcode{long double}. +\end{itemize} + +\pnum +The conversion occurs as if performed by the following code fragment +(using the same notation as for the preceding code fragment): +\begin{codeblock} +using numget = num_get>; +iostate err = ios_base::goodbit; +FP fval; +use_facet(loc).get(*this, 0, *this, err, fval); +if (fval < -numeric_limits<@\placeholder{extended-floating-point-type}@>::max()) { + err |= ios_base::failbit; + val = -numeric_limits<@\placeholder{extended-floating-point-type}@>::max(); +} else if (numeric_limits<@\placeholder{extended-floating-point-type}@>::max() < fval) { + err |= ios_base::failbit; + val = numeric_limits<@\placeholder{extended-floating-point-type}@>::max(); +} else { + val = static_cast<@\placeholder{extended-floating-point-type}@>(fval); +} +setstate(err); +\end{codeblock} +\begin{note} +When the extended floating-point type has +a floating-point conversion rank +that is not equal to the rank of any standard floating-point type, +then double rounding during the conversion can result in inaccurate results. +\tcode{from_chars} can be used in situations +where maximum accuracy is important. +\end{note} +\end{itemdescr} + \rSec4[istream.extractors]{\tcode{basic_istream::operator>>}} \indexlibrarymember{operator>>}{basic_istream}% @@ -5811,6 +5877,12 @@ \rSec4[ostream.general]{General} +\pnum +When a function has +a parameter type \tcode{\placeholder{extended-floating-point-type}}, +the implementation provides overloads +for all cv-unqualified extended floating-point types\iref{basic.fundamental}. + \indexlibraryglobal{basic_ostream}% \begin{codeblock} namespace std { @@ -5848,6 +5920,7 @@ basic_ostream& operator<<(float f); basic_ostream& operator<<(double f); basic_ostream& operator<<(long double f); + basic_ostream& operator<<(@\placeholder{extended-floating-point-type}@ f); basic_ostream& operator<<(const void* p); basic_ostream& operator<<(const volatile void* p); @@ -6427,6 +6500,44 @@ Equivalent to: \tcode{return operator<<(const_cast(p));} \end{itemdescr} +\begin{itemdecl} +basic_ostream& operator<<(@\placeholder{extended-floating-point-type}@ val); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{double}, +the formatting conversion occurs as if it performed the following code fragment: +\begin{codeblock} +bool failed = use_facet< + num_put> + >(getloc()).put(*this, *this, fill(), + static_cast(val)).failed(); +\end{codeblock} +Otherwise, +if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} +is less than or equal to that of \tcode{long double}, +the formatting conversion occurs as if it performed the following code fragment: +\begin{codeblock} +bool failed = use_facet< + num_put> + >(getloc()).put(*this, *this, fill(), + static_cast(val)).failed(); +\end{codeblock} +Otherwise, an invocation of the operator function is conditionally supported +with \impldef{\tcode{operator<<} for large extended floating-point types} +semantics. + +If \tcode{failed} is \tcode{true} then does \tcode{setstate(badbit)}, +which may throw an exception, and returns. + +\pnum +\returns +\tcode{*this}. +\end{itemdescr} + \rSec4[ostream.inserters]{\tcode{basic_ostream::operator<<}} \indexlibrarymember{operator<<}{basic_ostream}% diff --git a/source/lex.tex b/source/lex.tex index afc0772746..9c8c403056 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1728,7 +1728,7 @@ \begin{bnf} \nontermdef{floating-point-suffix} \textnormal{one of}\br - \terminal{f l F L} + \terminal{f l f16 f32 f64 f128 bf16 F L F16 F32 F64 F128 BF16} \end{bnf} \pnum @@ -1739,8 +1739,16 @@ \indextext{suffix!\idxcode{L}}% \indextext{suffix!\idxcode{l}}% \indextext{literal!\idxcode{long double}}% -The type of a \grammarterm{floating-point-literal} is determined by +The type of +a \grammarterm{floating-point-literal}\iref{basic.fundamental,basic.extended.fp} +is determined by its \grammarterm{floating-point-suffix} as specified in \tref{lex.fcon.type}. +\begin{note} +The floating-point suffixes +\tcode{f16}, \tcode{f32}, \tcode{f64}, \tcode{f128}, \tcode{bf16}, +\tcode{F16}, \tcode{F32}, \tcode{F64}, \tcode{F128}, and \tcode{BF16} +are conditionally-supported. See \ref{basic.extended.fp}. +\end{note} \begin{simpletypetable} {Types of \grammarterm{floating-point-literal}{s}} {lex.fcon.type} @@ -1750,6 +1758,11 @@ none & \keyword{double} \\ \tcode{f} or \tcode{F} & \keyword {float} \\ \tcode{l} or \tcode{L} & \keyword{long} \keyword{double} \\ +\tcode{f16} or \tcode{F16} & \tcode{std::float16_t} \\ +\tcode{f32} or \tcode{F32} & \tcode{std::float32_t} \\ +\tcode{f64} or \tcode{F64} & \tcode{std::float64_t} \\ +\tcode{f128} or \tcode{F128} & \tcode{std::float128_t} \\ +\tcode{bf16} or \tcode{BF16} & \tcode{std::bfloat16_t} \\ \end{simpletypetable} \pnum diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 93e3a47587..3ddadeaf3d 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1073,6 +1073,7 @@ \tcode{} \\ \columnbreak \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/numerics.tex b/source/numerics.tex index 8d7df319d7..c940e27b47 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -190,13 +190,11 @@ and numerous functions for representing and manipulating complex numbers. \pnum -The effect of instantiating the template -\tcode{complex} -for any type other than \tcode{float}, \tcode{double}, or \tcode{long double} is unspecified. -The specializations -\tcode{complex}, -\tcode{complex}, and -\tcode{complex} are literal types\iref{term.literal.type}. +The effect of instantiating the template \tcode{complex} for any type +that is not a cv-unqualified floating-point type\iref{basic.fundamental} +is unspecified. +Specializations of \tcode{complex} for cv-unqualified floating-point types +are trivially-copyable literal types\iref{term.literal.type}. \pnum If the result of a function is not mathematically defined or not in @@ -225,11 +223,6 @@ // \ref{complex}, class template \tcode{complex} template class complex; - // \ref{complex.special}, specializations - template<> class complex; - template<> class complex; - template<> class complex; - // \ref{complex.ops}, operators template constexpr complex operator+(const complex&, const complex&); template constexpr complex operator+(const complex&, const T&); @@ -321,8 +314,8 @@ using value_type = T; constexpr complex(const T& re = T(), const T& im = T()); - constexpr complex(const complex&); - template constexpr complex(const complex&); + constexpr complex(const complex&) = default; + template constexpr explicit(@\seebelow@) complex(const complex&); constexpr T real() const; constexpr void real(T); @@ -356,96 +349,6 @@ of a complex number. -\rSec2[complex.special]{Specializations} - -\begin{codeblock} -namespace std { - template<> class complex { - public: - using value_type = float; - - constexpr complex(float re = 0.0f, float im = 0.0f); - constexpr complex(const complex&) = default; - constexpr explicit complex(const complex&); - constexpr explicit complex(const complex&); - - constexpr float real() const; - constexpr void real(float); - constexpr float imag() const; - constexpr void imag(float); - - constexpr complex& operator= (float); - constexpr complex& operator+=(float); - constexpr complex& operator-=(float); - constexpr complex& operator*=(float); - constexpr complex& operator/=(float); - - constexpr complex& operator=(const complex&); - template constexpr complex& operator= (const complex&); - template constexpr complex& operator+=(const complex&); - template constexpr complex& operator-=(const complex&); - template constexpr complex& operator*=(const complex&); - template constexpr complex& operator/=(const complex&); - }; - - template<> class complex { - public: - using value_type = double; - - constexpr complex(double re = 0.0, double im = 0.0); - constexpr complex(const complex&); - constexpr complex(const complex&) = default; - constexpr explicit complex(const complex&); - - constexpr double real() const; - constexpr void real(double); - constexpr double imag() const; - constexpr void imag(double); - - constexpr complex& operator= (double); - constexpr complex& operator+=(double); - constexpr complex& operator-=(double); - constexpr complex& operator*=(double); - constexpr complex& operator/=(double); - - constexpr complex& operator=(const complex&); - template constexpr complex& operator= (const complex&); - template constexpr complex& operator+=(const complex&); - template constexpr complex& operator-=(const complex&); - template constexpr complex& operator*=(const complex&); - template constexpr complex& operator/=(const complex&); - }; - - template<> class complex { - public: - using value_type = long double; - - constexpr complex(long double re = 0.0L, long double im = 0.0L); - constexpr complex(const complex&); - constexpr complex(const complex&); - constexpr complex(const complex&) = default; - - constexpr long double real() const; - constexpr void real(long double); - constexpr long double imag() const; - constexpr void imag(long double); - - constexpr complex& operator= (long double); - constexpr complex& operator+=(long double); - constexpr complex& operator-=(long double); - constexpr complex& operator*=(long double); - constexpr complex& operator/=(long double); - - constexpr complex& operator=(const complex&); - template constexpr complex& operator= (const complex&); - template constexpr complex& operator+=(const complex&); - template constexpr complex& operator-=(const complex&); - template constexpr complex& operator*=(const complex&); - template constexpr complex& operator/=(const complex&); - }; -} -\end{codeblock} - \rSec2[complex.members]{Member functions} \indexlibraryctor{complex}% @@ -459,6 +362,24 @@ \tcode{real() == re \&\& imag() == im} is \tcode{true}. \end{itemdescr} +\indexlibraryctor{complex}% +\begin{itemdecl} +template constexpr explicit(@\seebelow@) complex(const complex& other); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes the real part with \tcode{other.real()} and +the imaginary part with \tcode{other.imag()}. + +\pnum +\remarks +The expression inside \tcode{explicit} evaluates to \tcode{false} +if and only if the floating-point conversion rank of \tcode{T} +is greater than or equal to the floating-point conversion rank of \tcode{X}. +\end{itemdescr} + \indexlibrarymember{real}{complex}% \begin{itemdecl} constexpr T real() const; @@ -1203,28 +1124,22 @@ \indextext{overloads!floating-point}% The additional overloads shall be sufficient to ensure: \begin{itemize} - \item If the argument has type \tcode{long double}, then it is effectively - cast to \tcode{complex}. - \item Otherwise, if the argument has type \tcode{double} or an integer type, - then it is effectively cast to \tcode{complex<\brk{}double>}. - \item Otherwise, if the argument has type \tcode{float}, then it is - effectively cast to \tcode{complex}. +\item +If the argument has a floating-point type \tcode{T}, +then it is effectively cast to \tcode{complex}. +\item +Otherwise, if the argument has integer type, +then it is effectively cast to \tcode{complex}. \end{itemize} \pnum \indexlibraryglobal{pow}% -Function template \tcode{pow} shall have additional overloads sufficient to -ensure, for a call with at least one argument of type \tcode{complex}: -\begin{itemize} - \item If either argument has type \tcode{complex} or type \tcode{long - double}, then both arguments are effectively cast to - \tcode{complex}. - \item Otherwise, if either argument has type \tcode{complex}, \tcode{double}, - or an integer type, then both arguments are effectively cast to - \tcode{complex}. - \item Otherwise, if either argument has type \tcode{complex} or \tcode{float}, - then both arguments are effectively cast to \tcode{complex}. -\end{itemize} +Function template \tcode{pow} has additional overloads sufficient to ensure, +for a call with one argument of type \tcode{complex} and +the other argument of type \tcode{T2} or \tcode{complex}, +both arguments are effectively cast to \tcode{complex>}. +If \tcode{common_type_t} is not well-formed, +then the program is ill-formed. \rSec2[complex.literals]{Suffixes for complex number literals} @@ -9029,171 +8944,115 @@ #define math_errhandling @\seebelow@ namespace std { - float acos(float x); // see \ref{library.c} - double acos(double x); - long double acos(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ acos(@\placeholder{floating-point-type}@ x); float acosf(float x); long double acosl(long double x); - float asin(float x); // see \ref{library.c} - double asin(double x); - long double asin(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ asin(@\placeholder{floating-point-type}@ x); float asinf(float x); long double asinl(long double x); - float atan(float x); // see \ref{library.c} - double atan(double x); - long double atan(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ atan(@\placeholder{floating-point-type}@ x); float atanf(float x); long double atanl(long double x); - float atan2(float y, float x); // see \ref{library.c} - double atan2(double y, double x); - long double atan2(long double y, long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ atan2(@\placeholder{floating-point-type}@ y, @\placeholder{floating-point-type}@ x); float atan2f(float y, float x); long double atan2l(long double y, long double x); - float cos(float x); // see \ref{library.c} - double cos(double x); - long double cos(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ cos(@\placeholder{floating-point-type}@ x); float cosf(float x); long double cosl(long double x); - float sin(float x); // see \ref{library.c} - double sin(double x); - long double sin(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ sin(@\placeholder{floating-point-type}@ x); float sinf(float x); long double sinl(long double x); - float tan(float x); // see \ref{library.c} - double tan(double x); - long double tan(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ tan(@\placeholder{floating-point-type}@ x); float tanf(float x); long double tanl(long double x); - float acosh(float x); // see \ref{library.c} - double acosh(double x); - long double acosh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ acosh(@\placeholder{floating-point-type}@ x); float acoshf(float x); long double acoshl(long double x); - float asinh(float x); // see \ref{library.c} - double asinh(double x); - long double asinh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ asinh(@\placeholder{floating-point-type}@ x); float asinhf(float x); long double asinhl(long double x); - float atanh(float x); // see \ref{library.c} - double atanh(double x); - long double atanh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ atanh(@\placeholder{floating-point-type}@ x); float atanhf(float x); long double atanhl(long double x); - float cosh(float x); // see \ref{library.c} - double cosh(double x); - long double cosh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ cosh(@\placeholder{floating-point-type}@ x); float coshf(float x); long double coshl(long double x); - float sinh(float x); // see \ref{library.c} - double sinh(double x); - long double sinh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ sinh(@\placeholder{floating-point-type}@ x); float sinhf(float x); long double sinhl(long double x); - float tanh(float x); // see \ref{library.c} - double tanh(double x); - long double tanh(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ tanh(@\placeholder{floating-point-type}@ x); float tanhf(float x); long double tanhl(long double x); - float exp(float x); // see \ref{library.c} - double exp(double x); - long double exp(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ exp(@\placeholder{floating-point-type}@ x); float expf(float x); long double expl(long double x); - float exp2(float x); // see \ref{library.c} - double exp2(double x); - long double exp2(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ exp2(@\placeholder{floating-point-type}@ x); float exp2f(float x); long double exp2l(long double x); - float expm1(float x); // see \ref{library.c} - double expm1(double x); - long double expm1(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ expm1(@\placeholder{floating-point-type}@ x); float expm1f(float x); long double expm1l(long double x); - constexpr float frexp(float value, int* exp); // see \ref{library.c} - constexpr double frexp(double value, int* exp); - constexpr long double frexp(long double value, int* exp); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ frexp(@\placeholder{floating-point-type}@ value, int* exp); constexpr float frexpf(float value, int* exp); constexpr long double frexpl(long double value, int* exp); - constexpr int ilogb(float x); // see \ref{library.c} - constexpr int ilogb(double x); - constexpr int ilogb(long double x); // see \ref{library.c} + constexpr int ilogb(@\placeholder{floating-point-type}@ x); constexpr int ilogbf(float x); constexpr int ilogbl(long double x); - constexpr float ldexp(float x, int exp); // see \ref{library.c} - constexpr double ldexp(double x, int exp); - constexpr long double ldexp(long double x, int exp); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ ldexp(@\placeholder{floating-point-type}@ x, int exp); constexpr float ldexpf(float x, int exp); constexpr long double ldexpl(long double x, int exp); - float log(float x); // see \ref{library.c} - double log(double x); - long double log(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log(@\placeholder{floating-point-type}@ x); float logf(float x); long double logl(long double x); - float log10(float x); // see \ref{library.c} - double log10(double x); - long double log10(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log10(@\placeholder{floating-point-type}@ x); float log10f(float x); long double log10l(long double x); - float log1p(float x); // see \ref{library.c} - double log1p(double x); - long double log1p(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log1p(@\placeholder{floating-point-type}@ x); float log1pf(float x); long double log1pl(long double x); - float log2(float x); // see \ref{library.c} - double log2(double x); - long double log2(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ log2(@\placeholder{floating-point-type}@ x); float log2f(float x); long double log2l(long double x); - constexpr float logb(float x); // see \ref{library.c} - constexpr double logb(double x); - constexpr long double logb(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ logb(@\placeholder{floating-point-type}@ x); constexpr float logbf(float x); constexpr long double logbl(long double x); - constexpr float modf(float value, float* iptr); // see \ref{library.c} - constexpr double modf(double value, double* iptr); - constexpr long double modf(long double value, long double* iptr); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ modf(@\placeholder{floating-point-type}@ value, @\placeholder{floating-point-type}@* iptr); constexpr float modff(float value, float* iptr); constexpr long double modfl(long double value, long double* iptr); - constexpr float scalbn(float x, int n); // see \ref{library.c} - constexpr double scalbn(double x, int n); - constexpr long double scalbn(long double x, int n); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ scalbn(@\placeholder{floating-point-type}@ x, int n); constexpr float scalbnf(float x, int n); constexpr long double scalbnl(long double x, int n); - constexpr float scalbln(float x, long int n); // see \ref{library.c} - constexpr double scalbln(double x, long int n); - constexpr long double scalbln(long double x, long int n); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ scalbln(@\placeholder{floating-point-type}@ x, long int n); constexpr float scalblnf(float x, long int n); constexpr long double scalblnl(long double x, long int n); - float cbrt(float x); // see \ref{library.c} - double cbrt(double x); - long double cbrt(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ cbrt(@\placeholder{floating-point-type}@ x); float cbrtf(float x); long double cbrtl(long double x); @@ -9201,144 +9060,97 @@ constexpr int abs(int j); constexpr long int abs(long int j); constexpr long long int abs(long long int j); - constexpr float abs(float j); - constexpr double abs(double j); - constexpr long double abs(long double j); + constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ j); - constexpr float fabs(float x); // see \ref{library.c} - constexpr double fabs(double x); - constexpr long double fabs(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fabs(@\placeholder{floating-point-type}@ x); constexpr float fabsf(float x); constexpr long double fabsl(long double x); - float hypot(float x, float y); // see \ref{library.c} - double hypot(double x, double y); - long double hypot(long double x, long double y); // see \ref{library.c} + @\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float hypotf(float x, float y); long double hypotl(long double x, long double y); // \ref{c.math.hypot3}, three-dimensional hypotenuse - float hypot(float x, float y, float z); - double hypot(double x, double y, double z); - long double hypot(long double x, long double y, long double z); + @\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, + @\placeholder{floating-point-type}@ z); - float pow(float x, float y); // see \ref{library.c} - double pow(double x, double y); - long double pow(long double x, long double y); // see \ref{library.c} + @\placeholder{floating-point-type}@ pow(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float powf(float x, float y); long double powl(long double x, long double y); - float sqrt(float x); // see \ref{library.c} - double sqrt(double x); - long double sqrt(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ sqrt(@\placeholder{floating-point-type}@ x); float sqrtf(float x); long double sqrtl(long double x); - float erf(float x); // see \ref{library.c} - double erf(double x); - long double erf(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ erf(@\placeholder{floating-point-type}@ x); float erff(float x); long double erfl(long double x); - float erfc(float x); // see \ref{library.c} - double erfc(double x); - long double erfc(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ erfc(@\placeholder{floating-point-type}@ x); float erfcf(float x); long double erfcl(long double x); - float lgamma(float x); // see \ref{library.c} - double lgamma(double x); - long double lgamma(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ lgamma(@\placeholder{floating-point-type}@ x); float lgammaf(float x); long double lgammal(long double x); - float tgamma(float x); // see \ref{library.c} - double tgamma(double x); - long double tgamma(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ tgamma(@\placeholder{floating-point-type}@ x); float tgammaf(float x); long double tgammal(long double x); - constexpr float ceil(float x); // see \ref{library.c} - constexpr double ceil(double x); - constexpr long double ceil(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ ceil(@\placeholder{floating-point-type}@ x); constexpr float ceilf(float x); constexpr long double ceill(long double x); - constexpr float floor(float x); // see \ref{library.c} - constexpr double floor(double x); - constexpr long double floor(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ floor(@\placeholder{floating-point-type}@ x); constexpr float floorf(float x); constexpr long double floorl(long double x); - float nearbyint(float x); // see \ref{library.c} - double nearbyint(double x); - long double nearbyint(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ nearbyint(@\placeholder{floating-point-type}@ x); float nearbyintf(float x); long double nearbyintl(long double x); - float rint(float x); // see \ref{library.c} - double rint(double x); - long double rint(long double x); // see \ref{library.c} + @\placeholder{floating-point-type}@ rint(@\placeholder{floating-point-type}@ x); float rintf(float x); long double rintl(long double x); - long int lrint(float x); // see \ref{library.c} - long int lrint(double x); - long int lrint(long double x); // see \ref{library.c} + long int lrint(@\placeholder{floating-point-type}@ x); long int lrintf(float x); long int lrintl(long double x); - long long int llrint(float x); // see \ref{library.c} - long long int llrint(double x); - long long int llrint(long double x); // see \ref{library.c} + long long int llrint(@\placeholder{floating-point-type}@ x); long long int llrintf(float x); long long int llrintl(long double x); - constexpr float round(float x); // see \ref{library.c} - constexpr double round(double x); - constexpr long double round(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ round(@\placeholder{floating-point-type}@ x); constexpr float roundf(float x); constexpr long double roundl(long double x); - constexpr long int lround(float x); // see \ref{library.c} - constexpr long int lround(double x); - constexpr long int lround(long double x); // see \ref{library.c} + constexpr long int lround(@\placeholder{floating-point-type}@ x); constexpr long int lroundf(float x); constexpr long int lroundl(long double x); - constexpr long long int llround(float x); // see \ref{library.c} - constexpr long long int llround(double x); - constexpr long long int llround(long double x); // see \ref{library.c} + constexpr long long int llround(@\placeholder{floating-point-type}@ x); constexpr long long int llroundf(float x); constexpr long long int llroundl(long double x); - constexpr float trunc(float x); // see \ref{library.c} - constexpr double trunc(double x); - constexpr long double trunc(long double x); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ trunc(@\placeholder{floating-point-type}@ x); constexpr float truncf(float x); constexpr long double truncl(long double x); - constexpr float fmod(float x, float y); // see \ref{library.c} - constexpr double fmod(double x, double y); - constexpr long double fmod(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fmod(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fmodf(float x, float y); constexpr long double fmodl(long double x, long double y); - constexpr float remainder(float x, float y); // see \ref{library.c} - constexpr double remainder(double x, double y); - constexpr long double remainder(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ remainder(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float remainderf(float x, float y); constexpr long double remainderl(long double x, long double y); - constexpr float remquo(float x, float y, int* quo); // see \ref{library.c} - constexpr double remquo(double x, double y, int* quo); - constexpr long double remquo(long double x, long double y, int* quo); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ remquo(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, int* quo); constexpr float remquof(float x, float y, int* quo); constexpr long double remquol(long double x, long double y, int* quo); - constexpr float copysign(float x, float y); // see \ref{library.c} - constexpr double copysign(double x, double y); - constexpr long double copysign(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ copysign(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float copysignf(float x, float y); constexpr long double copysignl(long double x, long double y); @@ -9346,202 +9158,156 @@ float nanf(const char* tagp); long double nanl(const char* tagp); - constexpr float nextafter(float x, float y); // see \ref{library.c} - constexpr double nextafter(double x, double y); - constexpr long double nextafter(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ nextafter(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float nextafterf(float x, float y); constexpr long double nextafterl(long double x, long double y); - constexpr float nexttoward(float x, long double y); // see \ref{library.c} - constexpr double nexttoward(double x, long double y); - constexpr long double nexttoward(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ nexttoward(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float nexttowardf(float x, long double y); constexpr long double nexttowardl(long double x, long double y); - constexpr float fdim(float x, float y); // see \ref{library.c} - constexpr double fdim(double x, double y); - constexpr long double fdim(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fdim(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fdimf(float x, float y); constexpr long double fdiml(long double x, long double y); - constexpr float fmax(float x, float y); // see \ref{library.c} - constexpr double fmax(double x, double y); - constexpr long double fmax(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fmax(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fmaxf(float x, float y); constexpr long double fmaxl(long double x, long double y); - constexpr float fmin(float x, float y); // see \ref{library.c} - constexpr double fmin(double x, double y); - constexpr long double fmin(long double x, long double y); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fmin(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); constexpr float fminf(float x, float y); constexpr long double fminl(long double x, long double y); - constexpr float fma(float x, float y, float z); // see \ref{library.c} - constexpr double fma(double x, double y, double z); - constexpr long double fma(long double x, long double y, long double z); // see \ref{library.c} + constexpr @\placeholder{floating-point-type}@ fma(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, + @\placeholder{floating-point-type}@ z); constexpr float fmaf(float x, float y, float z); constexpr long double fmal(long double x, long double y, long double z); // \ref{c.math.lerp}, linear interpolation - constexpr float lerp(float a, float b, float t) noexcept; - constexpr double lerp(double a, double b, double t) noexcept; - constexpr long double lerp(long double a, long double b, long double t) noexcept; + constexpr @\placeholder{floating-point-type}@ lerp(@\placeholder{floating-point-type}@ a, @\placeholder{floating-point-type}@ b, + @\placeholder{floating-point-type}@ t) noexcept; // \ref{c.math.fpclass}, classification / comparison functions - constexpr int fpclassify(float x); - constexpr int fpclassify(double x); - constexpr int fpclassify(long double x); - - constexpr bool isfinite(float x); - constexpr bool isfinite(double x); - constexpr bool isfinite(long double x); - - constexpr bool isinf(float x); - constexpr bool isinf(double x); - constexpr bool isinf(long double x); - - constexpr bool isnan(float x); - constexpr bool isnan(double x); - constexpr bool isnan(long double x); - - constexpr bool isnormal(float x); - constexpr bool isnormal(double x); - constexpr bool isnormal(long double x); - - constexpr bool signbit(float x); - constexpr bool signbit(double x); - constexpr bool signbit(long double x); - - constexpr bool isgreater(float x, float y); - constexpr bool isgreater(double x, double y); - constexpr bool isgreater(long double x, long double y); - - constexpr bool isgreaterequal(float x, float y); - constexpr bool isgreaterequal(double x, double y); - constexpr bool isgreaterequal(long double x, long double y); - - constexpr bool isless(float x, float y); - constexpr bool isless(double x, double y); - constexpr bool isless(long double x, long double y); - - constexpr bool islessequal(float x, float y); - constexpr bool islessequal(double x, double y); - constexpr bool islessequal(long double x, long double y); - - constexpr bool islessgreater(float x, float y); - constexpr bool islessgreater(double x, double y); - constexpr bool islessgreater(long double x, long double y); - - constexpr bool isunordered(float x, float y); - constexpr bool isunordered(double x, double y); - constexpr bool isunordered(long double x, long double y); + constexpr int fpclassify(@\placeholder{floating-point-type}@ x); + constexpr bool isfinite(@\placeholder{floating-point-type}@ x); + constexpr bool isinf(@\placeholder{floating-point-type}@ x); + constexpr bool isnan(@\placeholder{floating-point-type}@ x); + constexpr bool isnormal(@\placeholder{floating-point-type}@ x); + constexpr bool signbit(@\placeholder{floating-point-type}@ x); + constexpr bool isgreater(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool isgreaterequal(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool isless(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool islessequal(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool islessgreater(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); + constexpr bool isunordered(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); // \ref{sf.cmath}, mathematical special functions // \ref{sf.cmath.assoc.laguerre}, associated Laguerre polynomials - double assoc_laguerre(unsigned n, unsigned m, double x); + @\placeholder{floating-point-type}@ assoc_laguerre(unsigned n, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_laguerref(unsigned n, unsigned m, float x); long double assoc_laguerrel(unsigned n, unsigned m, long double x); // \ref{sf.cmath.assoc.legendre}, associated Legendre functions - double assoc_legendre(unsigned l, unsigned m, double x); + @\placeholder{floating-point-type}@ assoc_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_legendref(unsigned l, unsigned m, float x); long double assoc_legendrel(unsigned l, unsigned m, long double x); // \ref{sf.cmath.beta}, beta function - double beta(double x, double y); + @\placeholder{floating-point-type}@ beta(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float betaf(float x, float y); long double betal(long double x, long double y); // \ref{sf.cmath.comp.ellint.1}, complete elliptic integral of the first kind - double comp_ellint_1(double k); + @\placeholder{floating-point-type}@ comp_ellint_1(@\placeholder{floating-point-type}@ k); float comp_ellint_1f(float k); long double comp_ellint_1l(long double k); // \ref{sf.cmath.comp.ellint.2}, complete elliptic integral of the second kind - double comp_ellint_2(double k); + @\placeholder{floating-point-type}@ comp_ellint_2(@\placeholder{floating-point-type}@ k); float comp_ellint_2f(float k); long double comp_ellint_2l(long double k); // \ref{sf.cmath.comp.ellint.3}, complete elliptic integral of the third kind - double comp_ellint_3(double k, double nu); + @\placeholder{floating-point-type}@ comp_ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu); float comp_ellint_3f(float k, float nu); long double comp_ellint_3l(long double k, long double nu); // \ref{sf.cmath.cyl.bessel.i}, regular modified cylindrical Bessel functions - double cyl_bessel_i(double nu, double x); + @\placeholder{floating-point-type}@ cyl_bessel_i(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_if(float nu, float x); long double cyl_bessel_il(long double nu, long double x); // \ref{sf.cmath.cyl.bessel.j}, cylindrical Bessel functions of the first kind - double cyl_bessel_j(double nu, double x); + @\placeholder{floating-point-type}@ cyl_bessel_j(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_jf(float nu, float x); long double cyl_bessel_jl(long double nu, long double x); // \ref{sf.cmath.cyl.bessel.k}, irregular modified cylindrical Bessel functions - double cyl_bessel_k(double nu, double x); + @\placeholder{floating-point-type}@ cyl_bessel_k(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_kf(float nu, float x); long double cyl_bessel_kl(long double nu, long double x); - // \ref{sf.cmath.cyl.neumann}, cylindrical Neumann functions; + // \ref{sf.cmath.cyl.neumann}, cylindrical Neumann functions // cylindrical Bessel functions of the second kind - double cyl_neumann(double nu, double x); + @\placeholder{floating-point-type}@ cyl_neumann(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_neumannf(float nu, float x); long double cyl_neumannl(long double nu, long double x); // \ref{sf.cmath.ellint.1}, incomplete elliptic integral of the first kind - double ellint_1(double k, double phi); + @\placeholder{floating-point-type}@ ellint_1(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_1f(float k, float phi); long double ellint_1l(long double k, long double phi); // \ref{sf.cmath.ellint.2}, incomplete elliptic integral of the second kind - double ellint_2(double k, double phi); + @\placeholder{floating-point-type}@ ellint_2(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_2f(float k, float phi); long double ellint_2l(long double k, long double phi); // \ref{sf.cmath.ellint.3}, incomplete elliptic integral of the third kind - double ellint_3(double k, double nu, double phi); + @\placeholder{floating-point-type}@ ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu, + @\placeholder{floating-point-type}@ phi); float ellint_3f(float k, float nu, float phi); long double ellint_3l(long double k, long double nu, long double phi); // \ref{sf.cmath.expint}, exponential integral - double expint(double x); + @\placeholder{floating-point-type}@ expint(@\placeholder{floating-point-type}@ x); float expintf(float x); long double expintl(long double x); // \ref{sf.cmath.hermite}, Hermite polynomials - double hermite(unsigned n, double x); + @\placeholder{floating-point-type}@ hermite(unsigned n, @\placeholder{floating-point-type}@ x); float hermitef(unsigned n, float x); long double hermitel(unsigned n, long double x); // \ref{sf.cmath.laguerre}, Laguerre polynomials - double laguerre(unsigned n, double x); + @\placeholder{floating-point-type}@ laguerre(unsigned n, @\placeholder{floating-point-type}@ x); float laguerref(unsigned n, float x); long double laguerrel(unsigned n, long double x); // \ref{sf.cmath.legendre}, Legendre polynomials - double legendre(unsigned l, double x); + @\placeholder{floating-point-type}@ legendre(unsigned l, @\placeholder{floating-point-type}@ x); float legendref(unsigned l, float x); long double legendrel(unsigned l, long double x); // \ref{sf.cmath.riemann.zeta}, Riemann zeta function - double riemann_zeta(double x); + @\placeholder{floating-point-type}@ riemann_zeta(@\placeholder{floating-point-type}@ x); float riemann_zetaf(float x); long double riemann_zetal(long double x); // \ref{sf.cmath.sph.bessel}, spherical Bessel functions of the first kind - double sph_bessel(unsigned n, double x); + @\placeholder{floating-point-type}@ sph_bessel(unsigned n, @\placeholder{floating-point-type}@ x); float sph_besself(unsigned n, float x); long double sph_bessell(unsigned n, long double x); // \ref{sf.cmath.sph.legendre}, spherical associated Legendre functions - double sph_legendre(unsigned l, unsigned m, double theta); + @\placeholder{floating-point-type}@ sph_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ theta); float sph_legendref(unsigned l, unsigned m, float theta); long double sph_legendrel(unsigned l, unsigned m, long double theta); // \ref{sf.cmath.sph.neumann}, spherical Neumann functions; // spherical Bessel functions of the second kind - double sph_neumann(unsigned n, double x); + @\placeholder{floating-point-type}@ sph_neumann(unsigned n, @\placeholder{floating-point-type}@ x); float sph_neumannf(unsigned n, float x); long double sph_neumannl(unsigned n, long double x); } @@ -9560,33 +9326,30 @@ \end{note} \pnum -For each set of overloaded functions within \libheader{cmath}, -with the exception of \tcode{abs}, -there shall be additional overloads sufficient to ensure: -\begin{itemize} - \item If any argument of arithmetic type - corresponding to a \tcode{double} parameter - has type \tcode{long double}, - then all arguments of arithmetic type\iref{basic.fundamental} - corresponding to \tcode{double} parameters - are effectively cast to \tcode{long double}. - \item Otherwise, if any argument of arithmetic type - corresponding to a \tcode{double} parameter - has type \tcode{double} - or an integer type, - then all arguments of arithmetic type - corresponding to \tcode{double} parameters - are effectively cast to \tcode{double}. - \item -\begin{note} -Otherwise, all arguments of arithmetic type -corresponding to \tcode{double} parameters -have type \tcode{float}. -\end{note} -\end{itemize} -\begin{note} -\tcode{abs} is exempted from these rules in order to stay compatible with C. -\end{note} +For each function +with at least one parameter of type \placeholder{floating-point-type}, +the implementation provides +an overload for each cv-unqualified floating-point type\iref{basic.fundamental} +where all uses of \placeholder{floating-point-type} in the function signature +are replaced with that floating-point type. + +\pnum +For each function +with at least one parameter of type \placeholder{floating-point-type} +other than \tcode{abs}, +the implementation also provides additional overloads sufficient to ensure that, +if every argument corresponding to +a \placeholder{floating-point-type} parameter has arithmetic type, +then every such argument is effectively cast to the floating-point type +with the greatest floating-point conversion rank and +greatest floating-point conversion subrank +among the types of all such arguments, +where arguments of integer type are considered to have +the same floating-point conversion rank as \tcode{double}. +If no such floating-point type with the greatest rank and subrank exists, +then overload resolution does not result in +a usable candidate\iref{over.match.general} +from the overloads provided by the implementation. \xrefc{7.12} @@ -9604,22 +9367,18 @@ constexpr int abs(int j); constexpr long int abs(long int j); constexpr long long int abs(long long int j); -constexpr float abs(float j); -constexpr double abs(double j); -constexpr long double abs(long double j); \end{itemdecl} \begin{itemdescr} \pnum \effects -The \tcode{abs} +These functions have the semantics specified in the C standard library -for the functions \tcode{abs}, \tcode{labs}, \tcode{llabs}, -\tcode{fabsf}, \tcode{fabs}, and \tcode{fabsl}. +for the functions \tcode{abs}, \tcode{labs}, and \tcode{llabs}, respectively. \pnum \remarks -If \tcode{abs()} is called with an argument of type \tcode{X} +If \tcode{abs} is called with an argument of type \tcode{X} for which \tcode{is_unsigned_v} is \tcode{true} and if \tcode{X} cannot be converted to \tcode{int} by integral promotion\iref{conv.prom}, the program is ill-formed. @@ -9628,15 +9387,23 @@ \end{note} \end{itemdescr} +\begin{itemdecl} +constexpr @\placeholder{floating-point-type}@ abs(@\placeholder{floating-point-type}@ x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The absolute value of \tcode{x}. +\end{itemdescr} + \xrefc{7.12.7.2, 7.22.6.1} \rSec2[c.math.hypot3]{Three-dimensional hypotenuse} \indexlibrary{\idxcode{hypot}!3-argument form}% \begin{itemdecl} -float hypot(float x, float y, float z); -double hypot(double x, double y, double z); -long double hypot(long double x, long double y, long double z); +@\placeholder{floating-point-type}@ hypot(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y, double z); \end{itemdecl} \begin{itemdescr} @@ -9649,9 +9416,8 @@ \indexlibraryglobal{lerp}% \begin{itemdecl} -constexpr float lerp(float a, float b, float t) noexcept; -constexpr double lerp(double a, double b, double t) noexcept; -constexpr long double lerp(long double a, long double b, long double t) noexcept; +constexpr @\placeholder{floating-point-type}@ lerp(@\placeholder{floating-point-type}@ a, @\placeholder{floating-point-type}@ b, + @\placeholder{floating-point-type}@ t) noexcept; \end{itemdecl} \begin{itemdescr} \pnum @@ -9683,7 +9449,6 @@ \pnum The classification / comparison functions behave the same as the C macros with the corresponding names defined in the C standard library. -Each function is overloaded for the three floating-point types. \xrefc{7.12.3, 7.12.4} @@ -9748,7 +9513,7 @@ \indextext{Laguerre polynomials!$\mathsf{L}_n^m$}% \indextext{L nm@$\mathsf{L}_n^m$ (associated Laguerre polynomials)}% \begin{itemdecl} -double assoc_laguerre(unsigned n, unsigned m, double x); +@\placeholder{floating-point-type}@ assoc_laguerre(unsigned n, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_laguerref(unsigned n, unsigned m, float x); long double assoc_laguerrel(unsigned n, unsigned m, long double x); \end{itemdecl} @@ -9785,7 +9550,7 @@ \indextext{Legendre polynomials!$\mathsf{P}_\ell^m$}% \indextext{P lm@$\mathsf{P}_\ell^m$ (associated Legendre polynomials)}% \begin{itemdecl} -double assoc_legendre(unsigned l, unsigned m, double x); +@\placeholder{floating-point-type}@ assoc_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ x); float assoc_legendref(unsigned l, unsigned m, float x); long double assoc_legendrel(unsigned l, unsigned m, long double x); \end{itemdecl} @@ -9823,7 +9588,7 @@ \indextext{Eulerian integral of the first kind|see{beta functions $\mathsf{B}$}}% \indextext{beta functions $\mathsf{B}$}% \begin{itemdecl} -double beta(double x, double y); +@\placeholder{floating-point-type}@ beta(@\placeholder{floating-point-type}@ x, @\placeholder{floating-point-type}@ y); float betaf(float x, float y); long double betal(long double x, long double y); \end{itemdecl} @@ -9852,7 +9617,7 @@ \indextext{elliptic integrals!complete $\mathsf{K}$}% \indextext{K complete@$\mathsf{K}$ (complete elliptic integrals)}% \begin{itemdecl} -double comp_ellint_1(double k); +@\placeholder{floating-point-type}@ comp_ellint_1(@\placeholder{floating-point-type}@ k); float comp_ellint_1f(float k); long double comp_ellint_1l(long double k); \end{itemdecl} @@ -9882,7 +9647,7 @@ \indextext{elliptic integrals!complete $\mathsf{E}$}% \indextext{E complete@$\mathsf{E}$ (complete elliptic integrals)}% \begin{itemdecl} -double comp_ellint_2(double k); +@\placeholder{floating-point-type}@ comp_ellint_2(@\placeholder{floating-point-type}@ k); float comp_ellint_2f(float k); long double comp_ellint_2l(long double k); \end{itemdecl} @@ -9912,7 +9677,7 @@ \indextext{elliptic integrals!complete $\mathsf{\Pi}$}% \indextext{Pi complete@$\mathsf{\Pi}$ (complete elliptic integrals)}% \begin{itemdecl} -double comp_ellint_3(double k, double nu); +@\placeholder{floating-point-type}@ comp_ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu); float comp_ellint_3f(float k, float nu); long double comp_ellint_3l(long double k, long double nu); \end{itemdecl} @@ -9943,7 +9708,7 @@ \indextext{Bessel functions!$\mathsf{I}_\nu$}% \indextext{I nu@$\mathsf{I}_\nu$ (Bessell functions)}% \begin{itemdecl} -double cyl_bessel_i(double nu, double x); +@\placeholder{floating-point-type}@ cyl_bessel_i(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_if(float nu, float x); long double cyl_bessel_il(long double nu, long double x); \end{itemdecl} @@ -9983,7 +9748,7 @@ \indextext{Bessel functions!$\mathsf{J}_\nu$}% \indextext{J nu@$\mathsf{J}_\nu$ (Bessell functions)}% \begin{itemdecl} -double cyl_bessel_j(double nu, double x); +@\placeholder{floating-point-type}@ cyl_bessel_j(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_jf(float nu, float x); long double cyl_bessel_jl(long double nu, long double x); \end{itemdecl} @@ -10020,7 +9785,7 @@ \indextext{Bessel functions!$\mathsf{K}_\nu$}% \indextext{K nu@$\mathsf{K}_\nu$ (Bessell functions)}% \begin{itemdecl} -double cyl_bessel_k(double nu, double x); +@\placeholder{floating-point-type}@ cyl_bessel_k(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_bessel_kf(float nu, float x); long double cyl_bessel_kl(long double nu, long double x); \end{itemdecl} @@ -10081,7 +9846,7 @@ \indextext{Neumann functions!$\mathsf{N}_\nu$}% \indextext{N nu@$\mathsf{N}_\nu$ (Neumann functions)}% \begin{itemdecl} -double cyl_neumann(double nu, double x); +@\placeholder{floating-point-type}@ cyl_neumann(@\placeholder{floating-point-type}@ nu, @\placeholder{floating-point-type}@ x); float cyl_neumannf(float nu, float x); long double cyl_neumannl(long double nu, long double x); \end{itemdecl} @@ -10135,7 +9900,7 @@ \indextext{elliptic integrals!incomplete $\mathsf{F}$}% \indextext{F incomplete@$\mathsf{F}$ (incomplete elliptic integrals)}% \begin{itemdecl} -double ellint_1(double k, double phi); +@\placeholder{floating-point-type}@ ellint_1(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_1f(float k, float phi); long double ellint_1l(long double k, long double phi); \end{itemdecl} @@ -10165,7 +9930,7 @@ \indextext{elliptic integrals!incomplete $\mathsf{E}$}% \indextext{E incomplete@$\mathsf{E}$ (incomplete elliptic integrals)}% \begin{itemdecl} -double ellint_2(double k, double phi); +@\placeholder{floating-point-type}@ ellint_2(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ phi); float ellint_2f(float k, float phi); long double ellint_2l(long double k, long double phi); \end{itemdecl} @@ -10194,7 +9959,8 @@ \indextext{elliptic integrals!incomplete $\mathsf{\Pi}$}% \indextext{Pi incomplete@$\mathsf{\Pi}$ (incomplete elliptic integrals)}% \begin{itemdecl} -double ellint_3(double k, double nu, double phi); +@\placeholder{floating-point-type}@ ellint_3(@\placeholder{floating-point-type}@ k, @\placeholder{floating-point-type}@ nu, + @\placeholder{floating-point-type}@ phi); float ellint_3f(float k, float nu, float phi); long double ellint_3l(long double k, long double nu, long double phi); \end{itemdecl} @@ -10225,7 +9991,7 @@ \indextext{exponential integrals $\mathsf{Ei}$}% \indextext{Ei@$\mathsf{Ei}$ (exponential integrals)}% \begin{itemdecl} -double expint(double x); +@\placeholder{floating-point-type}@ expint(@\placeholder{floating-point-type}@ x); float expintf(float x); long double expintl(long double x); \end{itemdecl} @@ -10258,7 +10024,7 @@ \indextext{Hermite polynomials $\mathsf{H}_n$}% \indextext{H n@$\mathsf{H}_n$ (Hermite polynomials)}% \begin{itemdecl} -double hermite(unsigned n, double x); +@\placeholder{floating-point-type}@ hermite(unsigned n, @\placeholder{floating-point-type}@ x); float hermitef(unsigned n, float x); long double hermitel(unsigned n, long double x); \end{itemdecl} @@ -10296,7 +10062,7 @@ \indextext{Laguerre polynomials!$\mathsf{L}_n$}% \indextext{L n@$\mathsf{L}_n$ (Laguerre polynomials)}% \begin{itemdecl} -double laguerre(unsigned n, double x); +@\placeholder{floating-point-type}@ laguerre(unsigned n, @\placeholder{floating-point-type}@ x); float laguerref(unsigned n, float x); long double laguerrel(unsigned n, long double x); \end{itemdecl} @@ -10331,7 +10097,7 @@ \indextext{Legendre polynomials!$\mathsf{P}_\ell$}% \indextext{P l@$\mathsf{P}_\ell$ (Legendre polynomials)}% \begin{itemdecl} -double legendre(unsigned l, double x); +@\placeholder{floating-point-type}@ legendre(unsigned l, @\placeholder{floating-point-type}@ x); float legendref(unsigned l, float x); long double legendrel(unsigned l, long double x); \end{itemdecl} @@ -10366,7 +10132,7 @@ \indexlibraryglobal{riemann_zetal}% \indextext{zeta functions $\zeta$}% \begin{itemdecl} -double riemann_zeta(double x); +@\placeholder{floating-point-type}@ riemann_zeta(@\placeholder{floating-point-type}@ x); float riemann_zetaf(float x); long double riemann_zetal(long double x); \end{itemdecl} @@ -10415,7 +10181,7 @@ \indextext{Bessel functions!$\mathsf{j}_n$}% \indextext{j n@$\mathsf{j}_n$ (spherical Bessel functions)}% \begin{itemdecl} -double sph_bessel(unsigned n, double x); +@\placeholder{floating-point-type}@ sph_bessel(unsigned n, @\placeholder{floating-point-type}@ x); float sph_besself(unsigned n, float x); long double sph_bessell(unsigned n, long double x); \end{itemdecl} @@ -10453,7 +10219,7 @@ \indextext{Legendre functions $\mathsf{Y}_\ell^m$}% \indextext{Y lm@$\mathsf{Y}_\ell^m$ (spherical associated Legendre functions)}% \begin{itemdecl} -double sph_legendre(unsigned l, unsigned m, double theta); +@\placeholder{floating-point-type}@ sph_legendre(unsigned l, unsigned m, @\placeholder{floating-point-type}@ theta); float sph_legendref(unsigned l, unsigned m, float theta); long double sph_legendrel(unsigned l, unsigned m, long double theta); \end{itemdecl} @@ -10497,7 +10263,7 @@ \indextext{Neumann functions!$\mathsf{n}_n$}% \indextext{n n spherical@$\mathsf{n}_n$ (spherical Neumann functions)}% \begin{itemdecl} -double sph_neumann(unsigned n, double x); +@\placeholder{floating-point-type}@ sph_neumann(unsigned n, @\placeholder{floating-point-type}@ x); float sph_neumannf(unsigned n, float x); long double sph_neumannl(unsigned n, long double x); \end{itemdecl} diff --git a/source/overloading.tex b/source/overloading.tex index f970139fe5..0354d739e4 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -2706,6 +2706,34 @@ A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different. +\item +A conversion in either direction +between floating-point type \tcode{FP1} and floating-point type \tcode{FP2} +is better than a conversion in the same direction +between \tcode{FP1} and arithmetic type \tcode{T3} if +\begin{itemize} +\item +the floating-point conversion rank\iref{conv.rank} of \tcode{FP1} +is equal to the rank of \tcode{FP2}, and +\item +\tcode{T3} is not a floating-point type, or +\tcode{T3} is a floating-point type +whose rank is not equal to the rank of \tcode{FP1}, or +the floating-point conversion subrank\iref{conv.rank} of \tcode{FP2} +is greater than the subrank of \tcode{T3}. +\begin{example} +\begin{codeblock} +int f(std::float32_t); +int f(std::float64_t); +int f(long long); +float x; +std::float16_t y; +int i = f(x); // calls \tcode{f(std::float32_t)} on implementations where + // \tcode{float} and \tcode{std::float32_t} have equal conversion ranks +int j = f(y); // error: ambiguous, no equal conversion rank +\end{codeblock} +\end{example} +\end{itemize} \item If class diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 46aff75633..bbe740de9f 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1728,6 +1728,45 @@ \tcode{operator new(std::size_t, std::align_val_t)}, etc.\iref{expr.new}. \end{note} +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT16_T}}% +\mname{STDCPP_FLOAT16_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary16 +as an extended floating-point type\iref{basic.extended.fp}. + +\item +\indextext{__stdcpp_float32_t__@\mname{STDCPP_FLOAT32_T}}% +\mname{STDCPP_FLOAT32_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary32 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float64_t__@\mname{STDCPP_FLOAT64_T}}% +\mname{STDCPP_FLOAT64_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary64 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_FLOAT128_T}}% +\mname{STDCPP_FLOAT128_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports +the ISO/IEC/IEEE 60559 floating-point interchange format binary128 +as an extended floating-point type. + +\item +\indextext{__stdcpp_float16_t__@\mname{STDCPP_BFLOAT16_T}}% +\mname{STDCPP_BFLOAT16_T}\\ +Defined as the integer literal \tcode{1} +if and only if the implementation supports an extended floating-point type +with the properties described in \ref{basic.extended.fp}. + \item \indextext{__time__@\mname{TIME}}% \mname{TIME}\\ diff --git a/source/support.tex b/source/support.tex index 40ceef1aae..f3a481d2bd 100644 --- a/source/support.tex +++ b/source/support.tex @@ -27,6 +27,7 @@ \ref{support.limits} & Implementation properties & \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{cstdint} & Integer types & \tcode{} \\ \rowsep +\ref{stdfloat.syn} & Header \libheader{stdfloat} synopsis & \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 @@ -222,9 +223,7 @@ constexpr int abs(int j); constexpr long int abs(long int j); constexpr long long int abs(long long int j); - constexpr float abs(float j); - constexpr double abs(double j); - constexpr long double abs(long double 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); @@ -1436,11 +1435,15 @@ \begin{itemdescr} \pnum -\tcode{true} if and only if the type adheres to ISO/IEC/IEEE -60559. +\tcode{true} if and only if the type adheres to ISO/IEC/IEEE 60559. \begin{footnote} -ISO/IEC/IEEE 60559:2011 is the same as IEEE 754-2008. +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. @@ -1965,6 +1968,29 @@ respectively. \end{note} +\rSec1[stdfloat.syn]{Header \tcode{} synopsis} + +\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 diff --git a/source/threads.tex b/source/threads.tex index 58909c97cd..16de6eba03 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -3296,10 +3296,7 @@ \pnum \indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point}>}}% There are specializations of the \tcode{atomic_ref} class template -for the floating-point types -\tcode{float}, -\tcode{double}, and -\tcode{long double}. +for all cv-unqualified floating-point types. For each such type \tcode{\placeholder{floating-point}}, the specialization \tcode{atomic_ref<\placeholder{floating-\-point}>} provides additional atomic operations appropriate to floating-point types. @@ -4348,10 +4345,7 @@ \indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}}% \pnum There are specializations of the \tcode{atomic} -class template for the floating-point types -\tcode{float}, -\tcode{double}, and -\tcode{long double}. +class template for all cv-unqualified floating-point types. For each such type \tcode{\placeholdernc{floating-point}}, the specialization \tcode{atomic<\placeholder{floating-point}>} provides additional atomic operations appropriate to floating-point types. diff --git a/source/utilities.tex b/source/utilities.tex index 994bcc7c43..39ab1f815e 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -13019,6 +13019,18 @@ \rSec2[charconv.syn]{Header \tcode{} synopsis} +\pnum +When a function is specified +with a type placeholder of \tcode{\placeholder{integer-type}}, +the implementation provides overloads +for all cv-unqualified signed and unsigned integer types and \tcode{char} +in lieu of \tcode{\placeholder{integer-type}}. +When a function is specified +with a type placeholder of \tcode{\placeholder{floating-point-type}}, +the implementation provides overloads +for all cv-unqualified floating-point types\iref{basic.fundamental} +in lieu of \tcode{\placeholder{floating-point-type}}. + \indexheader{charconv}% \begin{codeblock} @% @@ -13047,22 +13059,12 @@ friend bool operator==(const to_chars_result&, const to_chars_result&) = default; }; - to_chars_result to_chars(char* first, char* last, @\seebelow@ value, int base = 10); + to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; - to_chars_result to_chars(char* first, char* last, float value); - to_chars_result to_chars(char* first, char* last, double value); - to_chars_result to_chars(char* first, char* last, long double value); - - to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); - to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); - to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); - - to_chars_result to_chars(char* first, char* last, float value, - chars_format fmt, int precision); - to_chars_result to_chars(char* first, char* last, double value, - chars_format fmt, int precision); - to_chars_result to_chars(char* first, char* last, long double value, + to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value); + to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt); + to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt, int precision); @% \indexlibraryglobal{from_chars_result}% @@ -13077,13 +13079,9 @@ }; from_chars_result from_chars(const char* first, const char* last, - @\seebelow@& value, int base = 10); + @\placeholder{integer-type}@& value, int base = 10); - from_chars_result from_chars(const char* first, const char* last, float& value, - chars_format fmt = chars_format::general); - from_chars_result from_chars(const char* first, const char* last, double& value, - chars_format fmt = chars_format::general); - from_chars_result from_chars(const char* first, const char* last, long double& value, + from_chars_result from_chars(const char* first, const char* last, @\placeholder{floating-point-type}@& value, chars_format fmt = chars_format::general); } \end{codeblock} @@ -13150,7 +13148,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, @\seebelow@ value, int base = 10); +to_chars_result to_chars(char* first, char* last, @\placeholder{integer-type}@ value, int base = 10); \end{itemdecl} \begin{itemdescr} @@ -13171,20 +13169,11 @@ \pnum \throws Nothing. - -\pnum -\remarks -The implementation shall provide overloads -for all signed and unsigned integer types -and \tcode{char} -as the type of the parameter \tcode{value}. \end{itemdescr} \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, float value); -to_chars_result to_chars(char* first, char* last, double value); -to_chars_result to_chars(char* first, char* last, long double value); +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value); \end{itemdecl} \begin{itemdescr} @@ -13205,9 +13194,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); -to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); -to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt); \end{itemdecl} \begin{itemdescr} @@ -13229,11 +13216,7 @@ \indexlibraryglobal{to_chars}% \begin{itemdecl} -to_chars_result to_chars(char* first, char* last, float value, - chars_format fmt, int precision); -to_chars_result to_chars(char* first, char* last, double value, - chars_format fmt, int precision); -to_chars_result to_chars(char* first, char* last, long double value, +to_chars_result to_chars(char* first, char* last, @\placeholder{floating-point-type}@ value, chars_format fmt, int precision); \end{itemdecl} @@ -13297,7 +13280,7 @@ \indexlibraryglobal{from_chars}% \begin{itemdecl} from_chars_result from_chars(const char* first, const char* last, - @\seebelow@&@\itcorr[-1]@ value, int base = 10); + @\placeholder{integer-type}@&@\itcorr[-1]@ value, int base = 10); \end{itemdecl} \begin{itemdescr} @@ -13320,22 +13303,11 @@ \pnum \throws Nothing. - -\pnum -\remarks -The implementation shall provide overloads -for all signed and unsigned integer types -and \tcode{char} -as the referenced type of the parameter \tcode{value}. \end{itemdescr} \indexlibraryglobal{from_chars}% \begin{itemdecl} -from_chars_result from_chars(const char* first, const char* last, float& value, - chars_format fmt = chars_format::general); -from_chars_result from_chars(const char* first, const char* last, double& value, - chars_format fmt = chars_format::general); -from_chars_result from_chars(const char* first, const char* last, long double& value, +from_chars_result from_chars(const char* first, const char* last, @\placeholder{floating-point-type}@& value, chars_format fmt = chars_format::general); \end{itemdecl} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 719ca93f9c..9677de5fb1 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -96,5 +96,8 @@ \movedxref{defns.direct-non-list-init}{defns.direct.non.list.init} \movedxref{defns.expression-equivalent}{defns.expression.equivalent} +% P1467R9 Extended floating-point types and standard names +\movedxref{complex.special}{complex.members} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)