diff --git a/docs/api_reference/src/quantities.tex b/docs/api_reference/src/quantities.tex index 6c45ca796..bd8f2e948 100644 --- a/docs/api_reference/src/quantities.tex +++ b/docs/api_reference/src/quantities.tex @@ -438,19 +438,18 @@ // \ref{qty.char.traits}, quantity character -template -constexpr bool is_scalar = @\seebelownc@; - -template -constexpr bool is_complex = false; template -constexpr bool @\libspec{is_complex}{std::complex}@> = true; +constexpr bool disable_scalar = false; +template<> +inline constexpr bool @\libspec{disable_scalar}{bool}@ = true; +template +constexpr bool @\libspec{disable_scalar}{std::complex}@> = true; -template -constexpr bool is_vector = false; +template +constexpr bool disable_complex = false; -template -constexpr bool is_tensor = false; +template +constexpr bool disable_vector = false; // \ref{qty.val.traits}, values @@ -465,7 +464,7 @@ inline constexpr @\unspec@ imag = @\unspec@; inline constexpr @\unspec@ modulus = @\unspec@; -inline constexpr @\unspec@ norm = @\unspec@; +inline constexpr @\unspec@ magnitude = @\unspec@; } @@ -3410,41 +3409,37 @@ \rSec3[qty.char.traits]{Quantity character} +\indexlibraryglobal{disable_scalar} +\indexlibraryglobal{disable_complex} +\indexlibraryglobal{disable_vector} \begin{itemdecl} -template -constexpr bool @\libglobal{is_scalar}@ = - std::is_floating_point_v || (std::is_integral_v && !std::is_same_v); - -template -constexpr bool @\libglobal{is_complex}@ = false; - -template -constexpr bool @\libglobal{is_vector}@ = false; - -template -constexpr bool @\libglobal{is_tensor}@ = false; +template +constexpr bool disable_scalar = false; +template +constexpr bool disable_complex = false; +template +constexpr bool disable_vector = false; \end{itemdecl} \begin{itemdescr} \pnum Some quantities are defined as having a numerical value\irefiev{112-01-29} of a specific set\irefiev{102-01-02}. The representation concepts use these traits -to determine the sets \tcode{T} represents. +to help determine the sets \tcode{T} represents. \pnum \remarks Pursuant to \refcpp{namespace.std}\iref{spec.ext}, -users may specialize \tcode{is_scalar}, \tcode{is_complex}, \tcode{is_vector}, and \tcode{is_tensor} to \tcode{true} -for cv-unqualified program-defined types -which respectively represent -a scalar\irefiev{102-02-18}, -a complex number\irefiev{102-02-09}, -a vector\irefiev{102-03-04}, and -% FIXME Undefined term. -a tensor, -and \tcode{false} for types which respectively do not. +users may specialize these templates +for cv-unqualified program-defined types. Such specializations shall be usable in constant expressions\irefcpp{expr.const} and have type \tcode{const bool}. + +\pnum +\begin{note} +These templates prevent use of representation types with the library +that satisfy but do not in fact model their corresponding concept. +\end{note} \end{itemdescr} \rSec3[qty.val.traits]{Values} @@ -3501,6 +3496,9 @@ Then: \begin{itemize} \item +If \tcode{T} does not model \exposconcept{WeaklyRegular}, +\tcode{mp_units::real(E)} is ill-formed. +\item If \tcode{auto(t.real())} is a valid expression whose type models \exposconcept{Scalar}, \tcode{mp_units::real(E)} is expression-equivalent to \tcode{auto(t.real())}. \item @@ -3523,6 +3521,9 @@ Then: \begin{itemize} \item +If \tcode{T} does not model \exposconcept{WeaklyRegular}, +\tcode{mp_units::imag(E)} is ill-formed. +\item If \tcode{auto(t.imag())} is a valid expression whose type models \exposconcept{Scalar}, \tcode{mp_units::imag(E)} is expression-equivalent to \tcode{auto(t.imag())}. \item @@ -3545,6 +3546,9 @@ Then: \begin{itemize} \item +If \tcode{T} does not model \exposconcept{WeaklyRegular}, +\tcode{mp_units::modulus(E)} is ill-formed. +\item If \tcode{auto(t.modulus())} is a valid expression whose type models \exposconcept{Scalar}, \tcode{mp_units::modulus(E)} is expression-equivalent to \tcode{auto(t.modulus())}. \item @@ -3553,6 +3557,9 @@ where the meaning of \tcode{modulus} is established as-if by performing argument-dependent lookup only\irefcpp{basic.lookup.argdep}, then \tcode{mp_units::modulus(E)} is expression-equivalent to that expression. \item +If \tcode{auto(t.abs())} is a valid expression whose type models \exposconcept{Scalar}, +\tcode{mp_units::modulus(E)} is expres\-sion-equivalent to \tcode{auto(t.abs())}. +\item Otherwise, if \tcode{T} is a class or enumeration type and \tcode{auto(abs(t))} is a valid expression whose type models \exposconcept{Scalar} where the meaning of \tcode{abs} is established as-if by performing argument-dependent lookup only\irefcpp{basic.lookup.argdep}, @@ -3561,10 +3568,10 @@ Otherwise, \tcode{mp_units::modulus(E)} is ill-formed. \end{itemize} -\rSec3[qty.norm.cpo]{\tcode{mp_units::norm}} +\rSec3[qty.mag.cpo]{\tcode{mp_units::magnitude}} \pnum -The name \tcode{mp_units::norm} denotes a customization point object\irefcpp{customization.point.object}. +The name \tcode{mp_units::magnitude} denotes a customization point object\irefcpp{customization.point.object}. \pnum Given a subexpression \tcode{E} with type \tcode{T}, @@ -3572,23 +3579,26 @@ Then: \begin{itemize} \item -If \tcode{auto(t.norm())} is a valid expression whose type models \exposconcept{Scalar}, -\tcode{mp_units::norm(E)} is expression-equivalent to \tcode{auto(t.norm())}. +If \tcode{T} does not model \exposconcept{WeaklyRegular}, +\tcode{mp_units::magnitude(E)} is ill-formed. +\item +If \tcode{auto(t.magnitude())} is a valid expression whose type models \exposconcept{Scalar}, +\tcode{mp_units::magnitude(E)} is expression-equivalent to \tcode{auto(t.magnitude())}. \item Otherwise, if \tcode{T} is a class or enumeration type and -\tcode{auto(norm(t))} is a valid expression whose type models \exposconcept{Scalar} -where the meaning of \tcode{norm} is established as-if by performing argument-dependent lookup only\irefcpp{basic.lookup.argdep}, -then \tcode{mp_units::norm(E)} is expression-equivalent to that expression. +\tcode{auto(magnitude(t))} is a valid expression whose type models \exposconcept{Scalar} +where the meaning of \tcode{magnitude} is established as-if by performing argument-dependent lookup only\irefcpp{basic.lookup.argdep}, +then \tcode{mp_units::magnitude(E)} is expression-equivalent to that expression. \item -Otherwise, if \tcode{auto(t.magnitude())} is a valid expression whose type models \exposconcept{Scalar}, -\tcode{mp_units::norm(\brk{}E)} is expression-equivalent to \tcode{auto(t.magnitude())}. +Otherwise, if \tcode{auto(t.abs())} is a valid expression whose type models \exposconcept{Scalar}, +\tcode{mp_units::magnitude(\brk{}E)} is expression-equivalent to \tcode{auto(t.abs())}. \item Otherwise, if \tcode{T} is a class or enumeration type and -\tcode{auto(mangnitude(t))} is a valid expression whose type models \exposconcept{Scalar} +\tcode{auto(abs(t))} is a valid expression whose type models \exposconcept{Scalar} where the meaning of \tcode{magnitude} is established as-if by performing argument-dependent lookup only\irefcpp{basic.lookup.argdep}, -then \tcode{mp_units::norm(E)} is expression-equivalent to that expression. +then \tcode{mp_units::magnitude(E)} is expression-equivalent to that expression. \item -Otherwise, \tcode{mp_units::norm(E)} is ill-formed. +Otherwise, \tcode{mp_units::magnitude(E)} is ill-formed. \end{itemize} \rSec2[qty.rep.concepts]{Concepts} @@ -3598,109 +3608,117 @@ concept @\defexposconceptnc{WeaklyRegular}@ = std::@\stdconcept{copyable}@ && std::@\stdconcept{equality_comparable}@; // \expos template -concept @\defexposconceptnc{Scalar}@ = is_scalar; // \expos - -template -concept @\defexposconceptnc{Complex}@ = is_complex; // \expos +concept @\defexposconceptnc{Scalar}@ = (!disable_scalar) && @\exposconceptnc{WeaklyRegular}@ && requires(T a, T b) { // \expos + // scalar operations + { -a } -> std::common_with; + { a + b } -> std::common_with; + { a - b } -> std::common_with; + { a * b } -> std::common_with; + { a / b } -> std::common_with; +}; +\end{itemdecl} -template -concept @\defexposconceptnc{Vector}@ = is_vector; // \expos +\pnum +TBD. +\begin{itemdecl} template -concept @\defexposconceptnc{Tensor}@ = is_tensor; // \expos - -template -concept @\defexposconceptnc{IsOfCharacter}@ = (Ch == quantity_character::scalar && is_scalar) || // \expos - (Ch == quantity_character::complex && is_complex) || - (Ch == quantity_character::vector && is_vector) || - (Ch == quantity_character::tensor && is_tensor); +using @\exposidnc{value-type-t}@ = @\exposidnc{actual-value-type-t}@; // \expos, see \ref{qty.fp.traits} template -using @\exposidnc{scaling-factor-type-t}@ = // \expos - conditional, long double, std::intmax_t>; +concept @\defexposconceptnc{Complex}@ = // \expos + (!disable_complex) && @\exposconceptnc{WeaklyRegular}@ && @\exposconceptnc{Scalar}@<@\exposidnc{value-type-t}@> && + std::constructible_from, @\exposidnc{value-type-t}@> && + requires(T a, T b, @\exposidnc{value-type-t}@ s) { + // complex operations + { -a } -> std::common_with; + { a + b } -> std::common_with; + { a - b } -> std::common_with; + { a * b } -> std::common_with; + { a / b } -> std::common_with; + { a * s } -> std::common_with; + { s * a } -> std::common_with; + { a / s } -> std::common_with; + mp_units::real(a); + mp_units::imag(a); + mp_units::modulus(a); + }; \end{itemdecl} +\pnum +TBD. + \begin{itemdecl} template -concept @\defexposconceptnc{ScalarRepresentation}@ = // \expos - @\exposconceptnc{Scalar}@ && @\exposconceptnc{WeaklyRegular}@ && requires(T a, T b, @\exposidnc{scaling-factor-type-t}@ f) { - // scaling - { a * f } -> Scalar; - { f * a } -> Scalar; - { a / f } -> Scalar; - - // scalar operations - { -a } -> Scalar; - { a + b } -> Scalar; - { a - b } -> Scalar; - { a * b } -> Scalar; - { a / b } -> Scalar; +concept @\defexposconceptnc{Vector}@ = // \expos + (!disable_vector) && @\exposconceptnc{WeaklyRegular}@ && @\exposconceptnc{Scalar}@<@\exposidnc{value-type-t}@> && + requires(T a, T b, @\exposidnc{value-type-t}@ s) { + // vector operations + { -a } -> std::common_with; + { a + b } -> std::common_with; + { a - b } -> std::common_with; + { a * s } -> std::common_with; + { s * a } -> std::common_with; + { a / s } -> std::common_with; + mp_units::magnitude(a); }; \end{itemdecl} \pnum -A type \tcode{T} models \exposconcept{ScalarRepresentation} if TBD. \begin{itemdecl} template -concept @\defexposconceptnc{ComplexRepresentation}@ = // \expos - @\exposconceptnc{Complex}@ && @\exposconceptnc{WeaklyRegular}@ && requires(T a, T b, @\exposidnc{scaling-factor-type-t}@ f) { - // scaling - { a * T(f) } -> Complex; - { T(f) * a } -> Complex; - { a / T(f) } -> Complex; +using @\exposidnc{scaling-factor-type-t}@ = // \expos + conditional, long double, std::intmax_t>; - // complex operations - { -a } -> Complex; - { a + b } -> Complex; - { a - b } -> Complex; - { a * b } -> Complex; - { a / b } -> Complex; - mp_units::real(a); - mp_units::imag(a); - mp_units::modulus(a); +template +concept @\defexposconceptnc{ScalarRepresentation}@ = // \expos + (!@\exposidnc{is-specialization-of}@()) && @\exposconceptnc{Scalar}@ && + requires(T a, T b, @\exposidnc{scaling-factor-type-t}@ f) { + // scaling + { a * f } -> std::common_with; + { f * a } -> std::common_with; + { a / f } -> std::common_with; }; \end{itemdecl} \pnum -A type \tcode{T} models \exposconcept{ComplexRepresentation} if TBD. \begin{itemdecl} template -concept @\defexposconceptnc{VectorRepresentation}@ = // \expos - @\exposconceptnc{Vector}@ && @\exposconceptnc{WeaklyRegular}@ && requires(T a, T b, @\exposidnc{scaling-factor-type-t}@ f) { +concept @\defexposconceptnc{ComplexRepresentation}@ = // \expos + (!@\exposidnc{is-specialization-of}@()) && @\exposconceptnc{Complex}@ && + requires(T a, T b, @\exposidnc{scaling-factor-type-t}@ f) { // scaling - { a * f } -> Vector; - { f * a } -> Vector; - { a / f } -> Vector; - - // vector operations - { -a } -> Vector; - { a + b } -> Vector; - { a - b } -> Vector; - mp_units::norm(a); + { a * T(f) } -> std::common_with; + { T(f) * a } -> std::common_with; + { a / T(f) } -> std::common_with; }; \end{itemdecl} \pnum -A type \tcode{T} models \exposconcept{VectorRepresentation} if TBD. \begin{itemdecl} template -concept @\defexposconceptnc{TensorRepresentation}@ = @\exposconceptnc{Tensor}@ && @\exposconceptnc{WeaklyRegular}@; // \expos +concept @\defexposconceptnc{VectorRepresentation}@ = // \expos + (!@\exposidnc{is-specialization-of}@()) && @\exposconceptnc{Vector}@; \end{itemdecl} \pnum -A type \tcode{T} models \exposconcept{TensorRepresentation} if TBD. \begin{itemdecl} +template +concept @\defexposconceptnc{IsOfCharacter}@ = (Ch == quantity_character::scalar && @\exposconceptnc{Scalar}@) || // \expos + (Ch == quantity_character::complex && @\exposconceptnc{Complex}@) || + (Ch == quantity_character::vector && @\exposconceptnc{Vector}@); + template concept @\deflibconcept{Representation}@ = @\exposconceptnc{ScalarRepresentation}@ || @\exposconceptnc{ComplexRepresentation}@ || - @\exposconceptnc{VectorRepresentation}@ || @\exposconceptnc{TensorRepresentation}@; + @\exposconceptnc{VectorRepresentation}@; \end{itemdecl} \pnum