Skip to content

Commit

Permalink
[quantities] Update representation concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP committed Nov 28, 2024
1 parent 5b420be commit 9874497
Showing 1 changed file with 123 additions and 105 deletions.
228 changes: 123 additions & 105 deletions docs/api_reference/src/quantities.tex
Original file line number Diff line number Diff line change
Expand Up @@ -438,19 +438,18 @@

// \ref{qty.char.traits}, quantity character

template<typename Rep>
constexpr bool is_scalar = @\seebelownc@;

template<typename Rep>
constexpr bool is_complex = false;
template<typename T>
constexpr bool @\libspec{is_complex}{std::complex}@<std::complex<T>> = true;
constexpr bool disable_scalar = false;
template<>
inline constexpr bool @\libspec{disable_scalar}{bool}@<bool> = true;
template<typename T>
constexpr bool @\libspec{disable_scalar}{std::complex}@<std::complex<T>> = true;

template<typename Rep>
constexpr bool is_vector = false;
template<typename T>
constexpr bool disable_complex = false;

template<typename Rep>
constexpr bool is_tensor = false;
template<typename T>
constexpr bool disable_vector = false;

// \ref{qty.val.traits}, values

Expand All @@ -465,7 +464,7 @@
inline constexpr @\unspec@ imag = @\unspec@;
inline constexpr @\unspec@ modulus = @\unspec@;

inline constexpr @\unspec@ norm = @\unspec@;
inline constexpr @\unspec@ magnitude = @\unspec@;

}

Expand Down Expand Up @@ -3410,41 +3409,37 @@
\rSec3[qty.char.traits]{Quantity character}
\indexlibraryglobal{disable_scalar}
\indexlibraryglobal{disable_complex}
\indexlibraryglobal{disable_vector}
\begin{itemdecl}
template<typename Rep>
constexpr bool @\libglobal{is_scalar}@ =
std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !std::is_same_v<Rep, bool>);
template<typename Rep>
constexpr bool @\libglobal{is_complex}@ = false;
template<typename Rep>
constexpr bool @\libglobal{is_vector}@ = false;
template<typename Rep>
constexpr bool @\libglobal{is_tensor}@ = false;
template<typename T>
constexpr bool disable_scalar = false;
template<typename T>
constexpr bool disable_complex = false;
template<typename T>
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}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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},
Expand All @@ -3561,34 +3568,37 @@
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},
let \tcode{t} be an lvalue that denotes the reified object for \tcode{E}.
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}
Expand All @@ -3598,109 +3608,117 @@
concept @\defexposconceptnc{WeaklyRegular}@ = std::@\stdconcept{copyable}@<T> && std::@\stdconcept{equality_comparable}@<T>; // \expos
template<typename T>
concept @\defexposconceptnc{Scalar}@ = is_scalar<T>; // \expos
template<typename T>
concept @\defexposconceptnc{Complex}@ = is_complex<T>; // \expos
concept @\defexposconceptnc{Scalar}@ = (!disable_scalar<T>) && @\exposconceptnc{WeaklyRegular}@<T> && requires(T a, T b) { // \expos
// scalar operations
{ -a } -> std::common_with<T>;
{ a + b } -> std::common_with<T>;
{ a - b } -> std::common_with<T>;
{ a * b } -> std::common_with<T>;
{ a / b } -> std::common_with<T>;
};
\end{itemdecl}
template<typename T>
concept @\defexposconceptnc{Vector}@ = is_vector<T>; // \expos
\pnum
TBD.
\begin{itemdecl}
template<typename T>
concept @\defexposconceptnc{Tensor}@ = is_tensor<T>; // \expos
template<typename T, quantity_character Ch>
concept @\defexposconceptnc{IsOfCharacter}@ = (Ch == quantity_character::scalar && is_scalar<T>) || // \expos
(Ch == quantity_character::complex && is_complex<T>) ||
(Ch == quantity_character::vector && is_vector<T>) ||
(Ch == quantity_character::tensor && is_tensor<T>);
using @\exposidnc{value-type-t}@ = @\exposidnc{actual-value-type-t}@<T>; // \expos, see \ref{qty.fp.traits}
template<typename T>
using @\exposidnc{scaling-factor-type-t}@ = // \expos
conditional<treat_as_floating_point<T>, long double, std::intmax_t>;
concept @\defexposconceptnc{Complex}@ = // \expos
(!disable_complex<T>) && @\exposconceptnc{WeaklyRegular}@<T> && @\exposconceptnc{Scalar}@<@\exposidnc{value-type-t}@<T>> &&
std::constructible_from<T, @\exposidnc{value-type-t}@<T>, @\exposidnc{value-type-t}@<T>> &&
requires(T a, T b, @\exposidnc{value-type-t}@<T> s) {
// complex operations
{ -a } -> std::common_with<T>;
{ a + b } -> std::common_with<T>;
{ a - b } -> std::common_with<T>;
{ a * b } -> std::common_with<T>;
{ a / b } -> std::common_with<T>;
{ a * s } -> std::common_with<T>;
{ s * a } -> std::common_with<T>;
{ a / s } -> std::common_with<T>;
mp_units::real(a);
mp_units::imag(a);
mp_units::modulus(a);
};
\end{itemdecl}
\pnum
TBD.
\begin{itemdecl}
template<typename T>
concept @\defexposconceptnc{ScalarRepresentation}@ = // \expos
@\exposconceptnc{Scalar}@<T> && @\exposconceptnc{WeaklyRegular}@<T> && requires(T a, T b, @\exposidnc{scaling-factor-type-t}@<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<T>) && @\exposconceptnc{WeaklyRegular}@<T> && @\exposconceptnc{Scalar}@<@\exposidnc{value-type-t}@<T>> &&
requires(T a, T b, @\exposidnc{value-type-t}@<T> s) {
// vector operations
{ -a } -> std::common_with<T>;
{ a + b } -> std::common_with<T>;
{ a - b } -> std::common_with<T>;
{ a * s } -> std::common_with<T>;
{ s * a } -> std::common_with<T>;
{ a / s } -> std::common_with<T>;
mp_units::magnitude(a);
};
\end{itemdecl}
\pnum
A type \tcode{T} models \exposconcept{ScalarRepresentation} if
TBD.
\begin{itemdecl}
template<typename T>
concept @\defexposconceptnc{ComplexRepresentation}@ = // \expos
@\exposconceptnc{Complex}@<T> && @\exposconceptnc{WeaklyRegular}@<T> && requires(T a, T b, @\exposidnc{scaling-factor-type-t}@<T> f) {
// scaling
{ a * T(f) } -> Complex;
{ T(f) * a } -> Complex;
{ a / T(f) } -> Complex;
using @\exposidnc{scaling-factor-type-t}@ = // \expos
conditional<treat_as_floating_point<T>, 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<typename T>
concept @\defexposconceptnc{ScalarRepresentation}@ = // \expos
(!@\exposidnc{is-specialization-of}@<T, quantity>()) && @\exposconceptnc{Scalar}@<T> &&
requires(T a, T b, @\exposidnc{scaling-factor-type-t}@<T> f) {
// scaling
{ a * f } -> std::common_with<T>;
{ f * a } -> std::common_with<T>;
{ a / f } -> std::common_with<T>;
};
\end{itemdecl}
\pnum
A type \tcode{T} models \exposconcept{ComplexRepresentation} if
TBD.
\begin{itemdecl}
template<typename T>
concept @\defexposconceptnc{VectorRepresentation}@ = // \expos
@\exposconceptnc{Vector}@<T> && @\exposconceptnc{WeaklyRegular}@<T> && requires(T a, T b, @\exposidnc{scaling-factor-type-t}@<T> f) {
concept @\defexposconceptnc{ComplexRepresentation}@ = // \expos
(!@\exposidnc{is-specialization-of}@<T, quantity>()) && @\exposconceptnc{Complex}@<T> &&
requires(T a, T b, @\exposidnc{scaling-factor-type-t}@<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>;
{ T(f) * a } -> std::common_with<T>;
{ a / T(f) } -> std::common_with<T>;
};
\end{itemdecl}
\pnum
A type \tcode{T} models \exposconcept{VectorRepresentation} if
TBD.
\begin{itemdecl}
template<typename T>
concept @\defexposconceptnc{TensorRepresentation}@ = @\exposconceptnc{Tensor}@<T> && @\exposconceptnc{WeaklyRegular}@<T>; // \expos
concept @\defexposconceptnc{VectorRepresentation}@ = // \expos
(!@\exposidnc{is-specialization-of}@<T, quantity>()) && @\exposconceptnc{Vector}@<T>;
\end{itemdecl}
\pnum
A type \tcode{T} models \exposconcept{TensorRepresentation} if
TBD.
\begin{itemdecl}
template<typename T, quantity_character Ch>
concept @\defexposconceptnc{IsOfCharacter}@ = (Ch == quantity_character::scalar && @\exposconceptnc{Scalar}@<T>) || // \expos
(Ch == quantity_character::complex && @\exposconceptnc{Complex}@<T>) ||
(Ch == quantity_character::vector && @\exposconceptnc{Vector}@<T>);
template<typename T>
concept @\deflibconcept{Representation}@ = @\exposconceptnc{ScalarRepresentation}@<T> || @\exposconceptnc{ComplexRepresentation}@<T> ||
@\exposconceptnc{VectorRepresentation}@<T> || @\exposconceptnc{TensorRepresentation}@<T>;
@\exposconceptnc{VectorRepresentation}@<T>;
\end{itemdecl}
\pnum
Expand Down

0 comments on commit 9874497

Please sign in to comment.