mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +02:00
267 lines
7.4 KiB
TeX
267 lines
7.4 KiB
TeX
%!TEX root = std.tex
|
|
\rSec0[qties]{Quantities library}
|
|
|
|
\rSec1[qties.summary]{Summary}
|
|
|
|
\pnum
|
|
This Clause describes components for dealing with quantities,
|
|
as summarized in \tref{qties.summary}.
|
|
|
|
\begin{modularlibsumtab}{Quantities library summary}{qties.summary}
|
|
\ref{qty.helpers} & Helpers & \tcode{mp_units.core} \\
|
|
\ref{qty.traits} & Traits & \\
|
|
\ref{qty.concepts} & Concepts & \\
|
|
\ref{qty.types} & Types & \\
|
|
\ref{qty.compat} & Compatibility & \\
|
|
\ref{qty.one} & Dimension one & \\ \rowsep
|
|
\ref{qty.systems} & Systems & \tcode{mp_units.systems} \\
|
|
\ref{qty.chrono} & \tcode{std::chrono} compatibility & \\
|
|
\end{modularlibsumtab}
|
|
|
|
\rSec1[mp.units.syn]{Module \tcode{mp_units} synopsis}
|
|
\indexmodule{mp_units}%
|
|
\begin{codeblock}
|
|
export module mp_units;
|
|
|
|
export import mp_units.core;
|
|
export import mp_units.systems;
|
|
\end{codeblock}
|
|
|
|
\rSec1[mp.units.core.syn]{Module \tcode{mp_units.core} synopsis}
|
|
\indexmodule{mp_units.core}%
|
|
\begin{codeblock}
|
|
export module mp_units.core;
|
|
|
|
import std;
|
|
|
|
export namespace mp_units {
|
|
|
|
export enum class quantity_character { scalar, vector, tensor };
|
|
|
|
// \ref{qty.traits}, traits
|
|
|
|
template<typename Rep>
|
|
constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>;
|
|
|
|
template<typename Rep>
|
|
constexpr bool is_scalar =
|
|
std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>);
|
|
|
|
template<typename Rep>
|
|
constexpr bool is_vector = false;
|
|
|
|
template<typename Rep>
|
|
constexpr bool is_tensor = false;
|
|
|
|
template<typename Rep>
|
|
struct quantity_values;
|
|
|
|
template<typename T>
|
|
struct quantity_like_traits;
|
|
|
|
template<typename T>
|
|
struct quantity_point_like_traits;
|
|
|
|
// \ref{qty.concepts}, concepts
|
|
|
|
template<typename T>
|
|
concept @\deflibconcept{some_reference}@ = template_of(^std::remove_cvref_t<T>) == ^reference;
|
|
|
|
template<typename T>
|
|
concept representation = @\seebelownc@;
|
|
|
|
template<typename T, quantity_character Ch>
|
|
concept representation_of = @\seebelownc@;
|
|
|
|
template<typename T>
|
|
concept some_quantity_spec = @\seebelownc@;
|
|
|
|
// \ref{qty.types}, types
|
|
|
|
template<auto...>
|
|
struct quantity_spec; // \notdef
|
|
|
|
template<auto Q>
|
|
struct kind_of_; // \notdef
|
|
|
|
template<@\unspec@... Expr>
|
|
struct derived_quantity_spec;
|
|
|
|
// \ref{qty.type}, class template \tcode{quantity}
|
|
export template<@\libconcept{some_reference}@ auto R,
|
|
@\libconcept{representation_of}@<get_quantity_spec(R).character> Rep = double>
|
|
class quantity;
|
|
|
|
// \ref{qty.point.type}, class template \tcode{quantity_point}
|
|
template<@\unspec@>
|
|
class quantity_point;
|
|
|
|
}
|
|
\end{codeblock}
|
|
|
|
\rSec1[mp.units.systems.syn]{Module \tcode{mp_units.systems} synopsis}
|
|
\indexmodule{mp_units.systems}%
|
|
\begin{codeblock}
|
|
export module mp_units.systems;
|
|
|
|
export import mp_units.core;
|
|
import std;
|
|
|
|
export namespace mp_units {
|
|
|
|
}
|
|
\end{codeblock}
|
|
|
|
\rSec1[qty.helpers]{Helpers}
|
|
|
|
\begin{itemdecl}
|
|
consteval bool @\exposidnc{converts-to-base-subobject-of}@(std::meta type, std::meta template_name);
|
|
\end{itemdecl}
|
|
|
|
\begin{itemdescr}
|
|
\pnum
|
|
\expects
|
|
\tcode{is_type(type) \&\& is_template(template_name)} is \tcode{true}.
|
|
|
|
\pnum
|
|
\returns
|
|
\tcode{true} if
|
|
\tcode{[:type:]} has an unambiguous and accessible base
|
|
that is a specialization of \tcode{[:template_name:]}, and
|
|
\tcode{false} otherwise.
|
|
\end{itemdescr}
|
|
|
|
\rSec1[qty.traits]{Traits}
|
|
|
|
\begin{itemdecl}
|
|
template<typename Rep>
|
|
constexpr bool @\libglobal{is_scalar}@ =
|
|
std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>);
|
|
|
|
template<typename Rep>
|
|
constexpr bool @\libglobal{is_vector}@ = false;
|
|
|
|
template<typename Rep>
|
|
constexpr bool @\libglobal{is_tensor}@ = false;
|
|
\end{itemdecl}
|
|
|
|
\begin{itemdescr}
|
|
\pnum
|
|
\remarks
|
|
Pursuant to \refcpp{namespace.std}\iref{spec.ext},
|
|
users may specialize \tcode{is_scalar}, \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 vector\irefiev{102-03-04}, and
|
|
% FIXME Undefined term.
|
|
a tensor,
|
|
and \tcode{false} for types which respectively do not.
|
|
\end{itemdescr}
|
|
|
|
\rSec1[qty.concepts]{Concepts}
|
|
|
|
\begin{itemdecl}
|
|
export template<typename T>
|
|
concept @\deflibconcept{representation}@ =
|
|
(is_scalar<T> || is_vector<T> || is_tensor<T>)&&std::regular<T> && @\exposidnc{scalable}@<T>;
|
|
\end{itemdecl}
|
|
|
|
\begin{itemdecl}
|
|
export template<typename T, quantity_character Ch>
|
|
concept @\deflibconcept{representation_of}@ =
|
|
@\libconcept{representation}@<T> && ((Ch == quantity_character::scalar && is_scalar<T>) ||
|
|
(Ch == quantity_character::vector && is_vector<T>) ||
|
|
(Ch == quantity_character::tensor && is_tensor<T>));
|
|
\end{itemdecl}
|
|
|
|
% FIXME Despite the `some_` prefix, it doesn't conform to the convention
|
|
% `template_of(^std::remove_cvref_t<T>) == ^template_name`.
|
|
\begin{itemdecl}
|
|
template<typename T>
|
|
concept @\defexposconceptnc{named-quantity-spec}@ =
|
|
(@\exposidnc{converts-to-base-subobject-of}@(^T, ^quantity_spec) && template_of(^T) != ^kind_of_);
|
|
|
|
template<typename T>
|
|
concept @\deflibconcept{some_quantity_spec}@ =
|
|
@\exposconceptnc{named-quantity-spec}@<T> ||
|
|
detail::IntermediateDerivedQuantitySpec<T> ||
|
|
template_of(^T) == ^kind_of;
|
|
\end{itemdecl}
|
|
|
|
\rSec1[qty.types]{Types}
|
|
|
|
\rSec2[qty.types.general]{General}
|
|
|
|
\pnum
|
|
A \defnadj{quantity}{type}
|
|
is a type \tcode{\placeholder{Q}}
|
|
that is a specialization of \tcode{quantity} or \tcode{quantity_point}.
|
|
\tcode{\placeholder{Q}} represents a quantity\irefiev{112-01-01}
|
|
with \tcode{\placeholder{Q}::rep} as its number
|
|
and \tcode{\placeholder{Q}::reference} as its reference.
|
|
\tcode{\placeholder{Q}} is a structural type\irefcppx{temp.param}{term.structural.type}
|
|
if \tcode{\placeholder{Q}::rep} is a structural type.
|
|
|
|
\pnum
|
|
Each class template defined in subclause \ref{qty.types}
|
|
has data members and special members specified below, and
|
|
has no base classes or members other than those specified.
|
|
|
|
\rSec2[qty.type]{Class template \tcode{quantity}}
|
|
|
|
\begin{codeblock}
|
|
namespace mp_units {
|
|
|
|
export template<@\libconcept{some_reference}@ auto R,
|
|
@\libconcept{representation_of}@<get_quantity_spec(R).character> Rep = double>
|
|
class quantity { @\unspec@ };
|
|
|
|
}
|
|
\end{codeblock}
|
|
|
|
Let \tcode{\placeholder{Q}} be a specialization of \tcode{quantity}.
|
|
\begin{itemize}
|
|
\item
|
|
If \tcode{Rep} is a scalar,
|
|
\tcode{\placeholder{Q}} represents a scalar quantity\irefiev{102-02-19}.
|
|
\item
|
|
If \tcode{Rep} is a vector,
|
|
\tcode{\placeholder{Q}} represents a vector\irefiev{102-03-04}.
|
|
% FIXME What if `Rep` is a tensor?
|
|
\end{itemize}
|
|
|
|
\rSec2[qty.point.type]{Class template \tcode{quantity_point}}
|
|
|
|
\begin{codeblock}
|
|
namespace mp_units {
|
|
|
|
export template<@\unspec@>
|
|
class quantity_point { @\unspec@ };
|
|
|
|
}
|
|
\end{codeblock}
|
|
|
|
A \defnadj{quantity point}{type} is a specialization of \tcode{quantity_point}.
|
|
Let \tcode{\placeholder{Q}} be a quantity point type.
|
|
\tcode{\placeholdernc{Q}::point_origin} represents
|
|
the origin point of a position vector\irefiev{102-03-15}.
|
|
\begin{itemize}
|
|
\item
|
|
If \tcode{Rep} is a scalar,
|
|
\tcode{\placeholder{Q}} represents the scalar quantity\irefiev{102-02-19}
|
|
of a position vector.
|
|
\item
|
|
If \tcode{Rep} is a vector,
|
|
\tcode{\placeholder{Q}} represents a position vector.
|
|
% FIXME What if `Rep` is a tensor?
|
|
\end{itemize}
|
|
|
|
\rSec1[qty.compat]{Compatibility}
|
|
|
|
\rSec1[qty.one]{Dimension one}
|
|
|
|
\rSec1[qty.systems]{Systems}
|
|
|
|
\rSec1[qty.chrono]{\tcode{std::chrono} compatibility}
|