-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs(ref): document mp_units.core
#628
base: master
Are you sure you want to change the base?
Changes from 10 commits
644b8d1
600a69b
e819430
9a9c343
543254a
d454ccc
60dd2cb
d9248b1
824f0c1
8bce9c6
58487d6
0cab71d
1f6be11
17585ce
9b35ad4
ae58e6c
14c0ee6
f542ffb
24842ca
ac09cec
399dcd0
2f8c2b1
aa5aa63
9ecd87e
49cb247
0248136
04eab10
71bfcf8
b94ec34
1917e12
2b23001
df90897
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -73,11 +73,11 @@ | |||
template<symbol_text Symbol> | ||||
struct base_dimension; | ||||
|
||||
template<@\seebelownc@> | ||||
template<typename... Expr> | ||||
struct derived_dimension; | ||||
|
||||
struct dimension_one; | ||||
inline constexpr dimension_one dimension_one = @\seebelownc@; | ||||
inline constexpr dimension_one @\libglobal{dimension_one}@{}; | ||||
|
||||
consteval @\libconcept{Dimension}@ auto @\liboverload{inverse}{\cname{Dimension}}@(@\libconcept{Dimension}@ auto d) { return dimension_one / d; } | ||||
|
||||
|
@@ -133,11 +133,11 @@ | |||
requires @\seebelownc@ | ||||
struct quantity_spec<QS, Eq, Args...>; | ||||
|
||||
template<@\exposconceptnc{DerivedQuantitySpecExpr}@... Expr> | ||||
template<typename Expr> | ||||
JohelEGP marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
struct derived_quantity_spec; | ||||
|
||||
struct dimensionless; | ||||
inline constexpr dimensionless dimensionless = @\seebelownc@; | ||||
inline constexpr dimensionless @\libglobal{dimensionless}@{}; | ||||
|
||||
template<typename Q> | ||||
requires @\seebelownc@ | ||||
|
@@ -181,7 +181,7 @@ | |||
requires(Value > 0) | ||||
struct mag_constant; | ||||
|
||||
template<@\exposconceptnc{MagnitudeSpecExpr}@ auto... Ms> | ||||
template<auto... Ms> | ||||
struct magnitude; | ||||
|
||||
template<@\exposconceptnc{MagArg}@ auto V> | ||||
|
@@ -274,11 +274,11 @@ | |||
template<@\libconcept{Unit}@ U1, @\libconcept{Unit}@ U2, @\libconcept{Unit}@... Rest> | ||||
struct common_unit; | ||||
|
||||
template<@\exposconceptnc{DerivedUnitExpr}@... Expr> | ||||
template<typename... Expr> | ||||
struct derived_unit; | ||||
|
||||
struct one; | ||||
inline constexpr one one = @\seebelownc@; | ||||
inline constexpr one @\libglobal{one}@{}; | ||||
|
||||
consteval @\libconcept{Unit}@ auto @\liboverload{inverse}{\cname{Unit}}@(@\libconcept{Unit}@ auto u) { return one / u; } | ||||
|
||||
|
@@ -570,24 +570,17 @@ | |||
|
||||
consteval bool is_integral(@\exposidnc{ratio}@ r) { return r.num % r.den == 0; } | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think it should be a public interface or exposition-only? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep it exposition-only unless there's a reason not to. |
||||
|
||||
consteval @\exposidnc{ratio}@ common_ratio(@\exposidnc{ratio}@ r1, @\exposidnc{ratio}@ r2) | ||||
{ | ||||
if (r1.num == r2.num && r1.den == r2.den) return r1; | ||||
|
||||
// $\operatorname{gcd}(a/b, c/d) = \operatorname{gcd}(ad, cb) / bd$ | ||||
contract_assert(std::numeric_limits<std::intmax_t>::max() / r1.num > r2.den); | ||||
contract_assert(std::numeric_limits<std::intmax_t>::max() / r2.num > r1.den); | ||||
contract_assert(std::numeric_limits<std::intmax_t>::max() / r1.den > r2.den); | ||||
|
||||
const std::intmax_t num = std::gcd(r1.num * r2.den, r2.num * r1.den); | ||||
const std::intmax_t den = r1.den * r2.den; | ||||
const std::intmax_t gcd = std::gcd(num, den); | ||||
return @\exposidnc{ratio}@{num / gcd, den / gcd}; | ||||
} | ||||
consteval @\exposidnc{ratio}@ common_ratio(@\exposidnc{ratio}@ r1, @\exposidnc{ratio}@ r2); | ||||
|
||||
} | ||||
\end{codeblock} | ||||
|
||||
\pnum | ||||
Unless otherwise specified, | ||||
in the following descriptions, | ||||
let \tcode{R(r)} be \tcode{std::ratio<N, D>}, | ||||
where \tcode{N} and \tcode{D} are the values of \tcode{r.num} and \tcode{r.den}. | ||||
|
||||
\begin{itemdecl} | ||||
consteval @\exposidnc{ratio}@(std::intmax_t n, std::intmax_t d = 1); | ||||
\end{itemdecl} | ||||
|
@@ -612,15 +605,30 @@ | |||
|
||||
\begin{itemdescr} | ||||
\pnum | ||||
Let \tcode{R(r)} be \tcode{std::ratio<N, D>}, | ||||
where \tcode{N} and \tcode{D} are the values of \tcode{r.num} and \tcode{r.den}. | ||||
Let \tcode{Res} be \tcode{std::ratio_multiply<R(lhs), R(rhs)>}. | ||||
|
||||
\pnum | ||||
\effects | ||||
Equivalent to: \tcode{return \exposidnc{ratio}\{Res::num, Res::den\}}. | ||||
\end{itemdescr} | ||||
|
||||
\begin{itemdecl} | ||||
consteval @\exposidnc{ratio}@ common_ratio(@\exposidnc{ratio}@ r1, @\exposidnc{ratio}@ r2); | ||||
\end{itemdecl} | ||||
|
||||
\begin{itemdescr} | ||||
\pnum | ||||
Let \tcode{Res} be | ||||
\begin{codeblock} | ||||
std::common_type<std::chrono::duration<int, R(r1)>, | ||||
std::chrono::duration<int, R(r2)>>::type::period | ||||
\end{codeblock} | ||||
|
||||
\pnum | ||||
\effects | ||||
Equivalent to: \tcode{return \exposidnc{ratio}\{Res::num, Res::den\}}. | ||||
\end{itemdescr} | ||||
|
||||
\rSec2[qty.fixed.string]{Class template \exposidnc{basic-fixed-string}} | ||||
|
||||
\rSec2[qty.symbol.text]{Class template \tcode{symbol_text}} | ||||
|
@@ -837,26 +845,6 @@ | |||
template<typename T> | ||||
concept @\defexposconceptnc{BaseDimension}@ = @\libconcept{Dimension}@<T> && std::@\stdconcept{derived_from}@<T, base_dimension>; | ||||
|
||||
consteval bool @\exposidnc{is-dimension-one}@(std::meta::info type_alias) { | ||||
return dealias(type_alias) == ^dimension_one; | ||||
} | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{IsPowerOfDim}@ = | ||||
(@\exposidnc{is-specialization-of}@(^T, ^power) && | ||||
(@\exposconceptnc{BaseDimension}@<typename T::factor> || @\exposidnc{is-dimension-one}@(^typename T::factor))); | ||||
|
||||
template<typename T> | ||||
constexpr bool @\exposidnc{is-per-of-dims}@ = false; | ||||
|
||||
template<typename... Ts> | ||||
constexpr bool @\exposidnc{is-per-of-dims}@<per<Ts...>> = | ||||
(... && (@\exposconceptnc{BaseDimension}@<Ts> || @\exposidnc{is-dimension-one}@(^Ts) || @\exposconceptnc{IsPowerOfDim}@<Ts>)); | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{DerivedDimensionExpr}@ = | ||||
@\exposconceptnc{BaseDimension}@<T> || @\exposidnc{is-dimension-one}@(^T) || @\exposconceptnc{IsPowerOfDim}@<T> || @\exposidnc{is-per-of-dims}@<T>; | ||||
|
||||
template<typename T, auto D> | ||||
concept @\deflibconcept{DimensionOf}@ = @\libconcept{Dimension}@<T> && @\libconcept{Dimension}@<decltype(D)> && T{} == D; | ||||
\end{itemdecl} | ||||
|
@@ -903,10 +891,10 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
template<@\exposconceptnc{DerivedDimensionExpr}@... Expr> | ||||
template<typename... Expr> | ||||
struct @\exposidnc{derived-dimension-impl}@ : @\exposidnc{expr-fractions}@<struct dimension_one, Expr...> {}; | ||||
|
||||
template<@\exposconceptnc{DerivedDimensionExpr}@... Expr> | ||||
template<typename... Expr> | ||||
struct @\libglobal{derived_dimension}@ final : @\exposidnc{dimension-interface}@, @\exposidnc{derived-dimension-impl}@<Expr...> {}; | ||||
|
||||
} | ||||
|
@@ -926,8 +914,7 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
inline constexpr struct @\libglobal{dimension_one}@ final : @\exposidnc{dimension-interface}@, @\exposidnc{derived-dimension-impl}@<> { | ||||
} @\libglobal{dimension_one}@; | ||||
struct @\libglobal{dimension_one}@ final : @\exposidnc{dimension-interface}@, @\exposidnc{derived-dimension-impl}@<> {}; | ||||
|
||||
} | ||||
\end{codeblock} | ||||
|
@@ -999,26 +986,6 @@ | |||
concept @\defexposconceptnc{NamedQuantitySpec}@ = | ||||
@\libconcept{QuantitySpec}@<T> && std::@\stdconcept{derived_from}@<T, quantity_spec> && !@\exposconceptnc{QuantityKindSpec}@<T>; | ||||
|
||||
consteval bool @\exposidnc{is-dimensionless}@(std::meta::info type_alias) { | ||||
return dealias(type_alias) == ^dimensionless; | ||||
} | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{IsPowerOfQuantitySpec}@ = | ||||
(@\exposidnc{is-specialization-of}@(^T, ^power) && | ||||
(@\exposconceptnc{NamedQuantitySpec}@<typename T::factor> || @\exposidnc{is-dimensionless}@(^typename T::factor))); | ||||
|
||||
template<typename T> | ||||
constexpr bool @\exposidnc{is-per-of-quantity-specs}@ = false; | ||||
|
||||
template<typename... Ts> | ||||
constexpr bool @\exposidnc{is-per-of-quantity-specs}@<per<Ts...>> = | ||||
(... && (@\exposconceptnc{NamedQuantitySpec}@<Ts> || @\exposidnc{is-dimensionless}@(^Ts) || @\exposconceptnc{IsPowerOfQuantitySpec}@<Ts>)); | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{DerivedQuantitySpecExpr}@ = @\exposconceptnc{NamedQuantitySpec}@<T> || @\exposidnc{is-dimensionless}@(^T) || | ||||
@\exposconceptnc{IsPowerOfQuantitySpec}@<T> || @\exposidnc{is-per-of-quantity-specs}@<T>; | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{DerivedQuantitySpec}@ = | ||||
@\libconcept{QuantitySpec}@<T> && | ||||
|
@@ -1263,7 +1230,7 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
template<@\exposconceptnc{DerivedQuantitySpecExpr}@... Expr> | ||||
template<typename... Expr> | ||||
struct @\exposidnc{derived-quantity-spec-impl}@ : | ||||
@\exposidnc{quantity-spec-interface}@, | ||||
@\exposidnc{expr-fractions}@<struct dimensionless, Expr...> { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this, I had a "chicken and egg problem". This is why I used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I had no idea. But the C++ standard specification is not code. But I suppose there'd be less friction There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see where a complete type for the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure what you mean. It is used here:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, yes, that's called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I never provided those in my implementation. It was your design change 😉 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This reference documentation doesn't need the
I also don't see where you need a complete type in mp-units. |
||||
|
@@ -1276,7 +1243,7 @@ | |||
@\exposidnc{derived-quantity-character}@(typename @\exposidnc{base}@::@\exposidnc{num}@{}, typename @\exposidnc{base}@::@\exposidnc{den}@{}); | ||||
}; | ||||
|
||||
template<@\exposconceptnc{DerivedQuantitySpecExpr}@... Expr> | ||||
template<typename... Expr> | ||||
struct @\libglobal{derived_quantity_spec}@ final : @\exposidnc{derived-quantity-spec-impl}@<Expr...> {}; | ||||
|
||||
} | ||||
|
@@ -1295,8 +1262,7 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
inline constexpr struct @\libglobal{dimensionless}@ final : quantity_spec<derived_quantity_spec<>> { | ||||
} @\libglobal{dimensionless}@; | ||||
struct @\libglobal{dimensionless}@ final : quantity_spec<derived_quantity_spec<>> {}; | ||||
|
||||
} | ||||
\end{codeblock} | ||||
|
@@ -1307,11 +1273,8 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{QuantitySpecWithNoSpecifiers}@ = @\exposconceptnc{NamedQuantitySpec}@<T> || @\exposconceptnc{DerivedQuantitySpec}@<T>; | ||||
|
||||
template<typename Q> | ||||
requires @\exposconceptnc{QuantitySpecWithNoSpecifiers}@<Q> && @\exposconceptnc{SameQuantitySpec}@<@\exposidnc{get-kind-tree-root}@(Q{}), Q{}> | ||||
requires(!@\exposconceptnc{QuantityKindSpec}@<Q>) && @\exposconceptnc{SameQuantitySpec}@<@\exposidnc{get-kind-tree-root}@(Q{}), Q{}> | ||||
struct @\libglobal{kind_of_}@ final : Q::@\exposidnc{base-type}@ { | ||||
using @\exposidnc{base-type}@ = kind_of_; | ||||
static constexpr auto @\exposidnc{quantity-spec}@ = Q{}; | ||||
|
@@ -1576,12 +1539,6 @@ | |||
template<typename T> | ||||
concept @\deflibconcept{MagConstant}@ = @\exposidnc{tag-type}@<T> && @\exposidnc{is-convertible-to-base-subobject-of}@(^T, ^mag_constant); | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{PowerVBase}@ = (^T == ^int) || ^T == ^std::intmax_t || @\libconcept{MagConstant}@<T>; | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{MagnitudeSpecExpr}@ = @\exposconceptnc{PowerVBase}@<T> || @\unspecnc@; | ||||
|
||||
template<typename T> | ||||
concept @\deflibconcept{Magnitude}@ = @\exposidnc{is-specialization-of}@(^T, ^magnitude); | ||||
|
||||
|
@@ -1611,19 +1568,22 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
template<@\exposconceptnc{MagnitudeSpecExpr}@ auto... Ms> | ||||
template<auto... Ms> | ||||
struct @\libglobal{magnitude}@ { | ||||
friend consteval @\libconcept{Magnitude}@ auto operator*(magnitude m1, @\libconcept{Magnitude}@ auto m2); | ||||
friend consteval @\libconcept{Magnitude}@ auto operator*(magnitude lhs, @\libconcept{Magnitude}@ auto rhs); | ||||
|
||||
friend consteval auto operator/(magnitude l, @\libconcept{Magnitude}@ auto r) { return l * @\exposidnc{pow}@<-1>(r); } | ||||
friend consteval auto operator/(magnitude lhs, @\libconcept{Magnitude}@ auto rhs) | ||||
{ | ||||
return lhs * @\exposidnc{pow}@<-1>(rhs); | ||||
} | ||||
|
||||
template<int Num, int Den = 1> | ||||
friend consteval auto @\exposidnc{pow}@(magnitude); | ||||
|
||||
template<@\libconcept{Magnitude}@ M2> | ||||
friend consteval bool operator==(magnitude, M2) | ||||
template<@\libconcept{Magnitude}@ Rhs> | ||||
friend consteval bool operator==(magnitude, Rhs) | ||||
{ | ||||
return ^magnitude == ^M2; | ||||
return ^magnitude == ^Rhs; | ||||
} | ||||
|
||||
friend consteval bool @\exposidnc{is-positive-integral-power}@(magnitude); | ||||
|
@@ -1637,7 +1597,7 @@ | |||
represents the product of its template arguments. | ||||
|
||||
\begin{itemdecl} | ||||
friend consteval @\libconcept{Magnitude}@ auto operator*(magnitude m1, @\libconcept{Magnitude}@ auto m2); | ||||
friend consteval @\libconcept{Magnitude}@ auto operator*(magnitude lhs, @\libconcept{Magnitude}@ auto rhs); | ||||
\end{itemdecl} | ||||
|
||||
\begin{itemdescr} | ||||
|
@@ -1647,7 +1607,7 @@ | |||
\item | ||||
If the type of a parameter is \tcode{magnitude<>}, returns the other parameter. | ||||
\item | ||||
Otherwise, returns an unspecified model of \libconcept{Magnitude} equal to $\tcode{m1} \times \tcode{m2}$. | ||||
Otherwise, returns an unspecified model of \libconcept{Magnitude} equal to $\tcode{lhs} \times \tcode{rhs}$. | ||||
\end{itemize} | ||||
\end{itemdescr} | ||||
|
||||
|
@@ -1744,20 +1704,6 @@ | |||
template<typename T> | ||||
concept @\deflibconcept{PrefixableUnit}@ = @\libconcept{Unit}@<T> && @\exposidnc{is-convertible-to-base-subobject-of}@(^T, ^named_unit); | ||||
|
||||
template<typename T> | ||||
constexpr bool @\exposidnc{is-power-of-unit}@ = requires { | ||||
requires @\exposidnc{is-convertible-to-base-subobject-of}@(^T, ^power) && @\libconcept{Unit}@<typename T::factor>; | ||||
}; | ||||
|
||||
template<typename T> | ||||
constexpr bool @\exposidnc{is-per-of-units}@ = false; | ||||
|
||||
template<typename... Ts> | ||||
constexpr bool @\exposidnc{is-per-of-units}@<per<Ts...>> = (... && (@\libconcept{Unit}@<Ts> || @\exposidnc{is-power-of-unit}@<Ts>)); | ||||
|
||||
template<typename T> | ||||
concept @\defexposconceptnc{DerivedUnitExpr}@ = @\libconcept{Unit}@<T> || @\exposidnc{is-power-of-unit}@<T> || @\exposidnc{is-per-of-units}@<T>; | ||||
|
||||
template<typename U, auto... Vs> | ||||
consteval bool @\exposidnc{has-associated-quantity}@(power<U, Vs...>) | ||||
{ | ||||
|
@@ -2052,15 +1998,15 @@ | |||
\pnum | ||||
\begin{example} | ||||
\begin{codeblock} | ||||
// The first signature defines a base unit restricted to a kind of quantity. | ||||
// The first signature defines a base unit restricted to a kind of base quantity. | ||||
inline constexpr struct second final : named_unit<"s", kind_of<time>> { | ||||
} second; | ||||
|
||||
// The third and fourth signatures give a name to the unit argument. | ||||
inline constexpr struct minute final : named_unit<"min", mag<60> * second> { | ||||
} minute; // $\txtrm{min} = 60 \txtrm{ s}$. | ||||
|
||||
// The fourth signature also restricts the unit to a kind of quantity. | ||||
// The fourth signature also further restricts the kind of quantity. | ||||
inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { | ||||
} hertz; // $\txtrm{Hz}$ can't measure becquerel, activity, | ||||
// or any other quantity with dimension $\txtrm{T}^{-1}$ | ||||
|
@@ -2144,11 +2090,14 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
template<@\exposconceptnc{DerivedUnitExpr}@... Expr> | ||||
struct @\libglobal{derived_unit}@ : @\exposidnc{unit-interface}@, @\exposidnc{expr-fractions}@<struct one, Expr...> { | ||||
using @\exposidnc{base-type}@ = derived_unit; // \expos | ||||
template<typename... Expr> | ||||
struct @\exposid{derived-unit-impl}@ : @\exposidnc{unit-interface}@, @\exposidnc{expr-fractions}@<struct one, Expr...> { | ||||
using @\exposidnc{base-type}@ = @\exposid{derived-unit-impl}@; // \expos | ||||
}; | ||||
|
||||
template<typename... Expr> | ||||
struct @\libglobal{derived_unit}@ final : @\exposid{derived-unit-impl}@<Expr...> {}; | ||||
|
||||
} | ||||
\end{codeblock} | ||||
|
||||
|
@@ -2166,7 +2115,7 @@ | |||
\begin{codeblock} | ||||
namespace mp_units { | ||||
|
||||
inline constexpr struct @\libglobal{one}@ final : derived_unit<> {} @\libglobal{one}@; | ||||
struct @\libglobal{one}@ final : @\exposid{derived-unit-impl}@<> {}; | ||||
|
||||
} | ||||
\end{codeblock} | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can we specify that some public identifiers should not be exported from the
std
module?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading https://wg21.link/std.modules, it seems like there's no way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will ask LWG members
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dropping in mid-stream here -- is there a problem with marking them as exposition only? That basically says -- we're going to act like this thing exists in the standard, but we might implement it differently or call it something different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exposition-only is not a solution, as I wrote in the LWG reflector.