From c362a533d6958ad564cd13fa006604a44e65878c Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 8 Dec 2024 08:57:12 +0000 Subject: [PATCH] Deployed 6d93f738 to HEAD with MkDocs 1.6.1 and mike 2.1.3 --- HEAD/api_reference/gen/assoc.qty.html | 35 + HEAD/api_reference/gen/conceptindex.html | 2 +- HEAD/api_reference/gen/defs.html | 4 +- HEAD/api_reference/gen/derived.qty.html | 38 + HEAD/api_reference/gen/dimless.qty.html | 6 + HEAD/api_reference/gen/full.html | 3535 ++++++++++++++++- HEAD/api_reference/gen/fulltoc.html | 2 +- HEAD/api_reference/gen/generalindex.html | 2 +- .../gen/get.common.qty.spec.html | 45 + HEAD/api_reference/gen/impldefindex.html | 1 + HEAD/api_reference/gen/index.html | 2 +- HEAD/api_reference/gen/kind.of.qty.html | 11 + HEAD/api_reference/gen/libraryindex.html | 2 +- HEAD/api_reference/gen/mp.units.core.syn.html | 634 ++- HEAD/api_reference/gen/mp.units.syn.html | 2 +- HEAD/api_reference/gen/mp.units.syns.html | 654 +++ .../gen/mp.units.systems.syn.html | 16 +- HEAD/api_reference/gen/named.qty.html | 65 + HEAD/api_reference/gen/qties.html | 144 - HEAD/api_reference/gen/qties.summary.html | 2 - HEAD/api_reference/gen/qty.abs.pt.orig.html | 10 + HEAD/api_reference/gen/qty.arith.ops.html | 74 + HEAD/api_reference/gen/qty.assign.ops.html | 43 + HEAD/api_reference/gen/qty.canon.unit.html | 11 + HEAD/api_reference/gen/qty.char.traits.html | 12 + HEAD/api_reference/gen/qty.chrono.html | 79 +- HEAD/api_reference/gen/qty.cmp.html | 29 + HEAD/api_reference/gen/qty.common.type.html | 21 + HEAD/api_reference/gen/qty.common.unit.html | 40 + HEAD/api_reference/gen/qty.compat.html | 1 - HEAD/api_reference/gen/qty.concepts.html | 18 - HEAD/api_reference/gen/qty.cons.html | 27 + HEAD/api_reference/gen/qty.conv.html | 29 + HEAD/api_reference/gen/qty.conv.ops.html | 17 + HEAD/api_reference/gen/qty.def.pt.orig.html | 8 + HEAD/api_reference/gen/qty.delta.html | 15 + HEAD/api_reference/gen/qty.derived.unit.html | 22 + HEAD/api_reference/gen/qty.dim.concepts.html | 10 + HEAD/api_reference/gen/qty.dim.general.html | 2 + HEAD/api_reference/gen/qty.dim.html | 75 + HEAD/api_reference/gen/qty.dim.ops.html | 27 + HEAD/api_reference/gen/qty.dim.sym.fmt.html | 7 + HEAD/api_reference/gen/qty.dim.types.html | 33 + HEAD/api_reference/gen/qty.fp.traits.html | 19 + HEAD/api_reference/gen/qty.general.html | 3 + .../gen/qty.get.common.base.html | 7 + HEAD/api_reference/gen/qty.get.kind.html | 18 + HEAD/api_reference/gen/qty.helpers.html | 5 - HEAD/api_reference/gen/qty.html | 708 ++++ HEAD/api_reference/gen/qty.imag.cpo.html | 8 + HEAD/api_reference/gen/qty.is.child.of.html | 4 + HEAD/api_reference/gen/qty.like.html | 20 + HEAD/api_reference/gen/qty.mag.cpo.html | 12 + HEAD/api_reference/gen/qty.modulus.cpo.html | 12 + HEAD/api_reference/gen/qty.named.unit.html | 81 + HEAD/api_reference/gen/qty.non.mem.conv.html | 41 + HEAD/api_reference/gen/qty.obs.html | 15 + HEAD/api_reference/gen/qty.one.html | 1 - HEAD/api_reference/gen/qty.point.html | 15 + HEAD/api_reference/gen/qty.point.type.html | 11 - HEAD/api_reference/gen/qty.prefixed.unit.html | 18 + HEAD/api_reference/gen/qty.pt.arith.ops.html | 51 + HEAD/api_reference/gen/qty.pt.assign.ops.html | 11 + HEAD/api_reference/gen/qty.pt.cmp.html | 16 + HEAD/api_reference/gen/qty.pt.cons.html | 34 + HEAD/api_reference/gen/qty.pt.conv.html | 38 + HEAD/api_reference/gen/qty.pt.conv.ops.html | 21 + HEAD/api_reference/gen/qty.pt.general.html | 3 + HEAD/api_reference/gen/qty.pt.html | 621 +++ HEAD/api_reference/gen/qty.pt.like.html | 10 + .../gen/qty.pt.non.mem.conv.html | 51 + HEAD/api_reference/gen/qty.pt.obs.html | 26 + .../gen/qty.pt.orig.concepts.html | 10 + .../gen/qty.pt.orig.general.html | 2 + HEAD/api_reference/gen/qty.pt.orig.html | 135 + HEAD/api_reference/gen/qty.pt.orig.ops.html | 70 + HEAD/api_reference/gen/qty.pt.orig.types.html | 34 + HEAD/api_reference/gen/qty.pt.orig.utils.html | 23 + HEAD/api_reference/gen/qty.pt.static.html | 7 + HEAD/api_reference/gen/qty.pt.syn.html | 199 + HEAD/api_reference/gen/qty.pt.unary.ops.html | 18 + HEAD/api_reference/gen/qty.ratio.html | 46 + HEAD/api_reference/gen/qty.real.cpo.html | 8 + HEAD/api_reference/gen/qty.ref.cmp.html | 11 + HEAD/api_reference/gen/qty.ref.concepts.html | 6 + HEAD/api_reference/gen/qty.ref.general.html | 2 + HEAD/api_reference/gen/qty.ref.html | 986 +++++ HEAD/api_reference/gen/qty.ref.obs.html | 27 + HEAD/api_reference/gen/qty.ref.ops.html | 34 + HEAD/api_reference/gen/qty.ref.syn.html | 67 + HEAD/api_reference/gen/qty.rel.pt.orig.html | 18 + HEAD/api_reference/gen/qty.rep.concepts.html | 88 + .../gen/qty.rep.cpos.general.html | 2 + HEAD/api_reference/gen/qty.rep.cpos.html | 38 + HEAD/api_reference/gen/qty.rep.general.html | 2 + HEAD/api_reference/gen/qty.rep.html | 166 + HEAD/api_reference/gen/qty.rep.traits.html | 41 + .../gen/qty.same.abs.pt.origs.html | 16 + HEAD/api_reference/gen/qty.scaled.unit.html | 15 + HEAD/api_reference/gen/qty.spec.concepts.html | 48 + HEAD/api_reference/gen/qty.spec.conv.html | 5 + HEAD/api_reference/gen/qty.spec.general.html | 2 + .../gen/qty.spec.hier.algos.html | 75 + HEAD/api_reference/gen/qty.spec.html | 306 ++ HEAD/api_reference/gen/qty.spec.ops.html | 46 + HEAD/api_reference/gen/qty.spec.types.html | 117 + HEAD/api_reference/gen/qty.spec.utils.html | 23 + HEAD/api_reference/gen/qty.static.html | 11 + .../api_reference/gen/qty.sym.expr.algos.html | 81 + .../gen/qty.sym.expr.concepts.html | 8 + .../gen/qty.sym.expr.general.html | 9 + HEAD/api_reference/gen/qty.sym.expr.html | 123 + .../api_reference/gen/qty.sym.expr.types.html | 28 + HEAD/api_reference/gen/qty.sym.txt.html | 80 + HEAD/api_reference/gen/qty.syn.html | 334 ++ HEAD/api_reference/gen/qty.systems.html | 2 +- HEAD/api_reference/gen/qty.traits.html | 17 - HEAD/api_reference/gen/qty.type.html | 10 - HEAD/api_reference/gen/qty.types.general.html | 8 - HEAD/api_reference/gen/qty.types.html | 27 - HEAD/api_reference/gen/qty.unary.ops.html | 31 + HEAD/api_reference/gen/qty.unit.cmp.html | 20 + HEAD/api_reference/gen/qty.unit.concepts.html | 34 + HEAD/api_reference/gen/qty.unit.general.html | 2 + HEAD/api_reference/gen/qty.unit.html | 466 +++ .../gen/qty.unit.mag.concepts.html | 9 + .../gen/qty.unit.mag.general.html | 3 + HEAD/api_reference/gen/qty.unit.mag.html | 83 + HEAD/api_reference/gen/qty.unit.mag.ops.html | 18 + .../api_reference/gen/qty.unit.mag.types.html | 50 + .../api_reference/gen/qty.unit.mag.utils.html | 7 + HEAD/api_reference/gen/qty.unit.obs.html | 44 + HEAD/api_reference/gen/qty.unit.one.html | 6 + HEAD/api_reference/gen/qty.unit.ops.html | 55 + HEAD/api_reference/gen/qty.unit.sym.fmt.html | 7 + HEAD/api_reference/gen/qty.unit.traits.html | 8 + HEAD/api_reference/gen/qty.unit.types.html | 187 + HEAD/api_reference/gen/qty.utils.html | 257 ++ .../gen/qty.utils.non.types.html | 11 + HEAD/api_reference/gen/qty.val.cmp.html | 13 + HEAD/api_reference/gen/qty.val.traits.html | 12 + .../api_reference/gen/qty.zeroth.pt.orig.html | 8 + HEAD/api_reference/gen/quantities.html | 3469 ++++++++++++++++ .../api_reference/gen/quantities.summary.html | 6 + HEAD/api_reference/gen/refs.html | 4 +- HEAD/api_reference/gen/scope.html | 2 +- HEAD/api_reference/gen/spec.cats.html | 6 +- HEAD/api_reference/gen/spec.ext.html | 4 +- HEAD/api_reference/gen/spec.html | 12 +- HEAD/api_reference/gen/spec.mods.html | 2 +- HEAD/api_reference/gen/spec.reqs.html | 2 +- HEAD/api_reference/gen/spec.res.names.html | 2 +- HEAD/api_reference/gen/tab.html | 2 +- HEAD/api_reference/gen/tab:lib.cats.html | 2 +- HEAD/api_reference/gen/tab:qties.summary.html | 1 - .../gen/tab:quantities.summary.html | 1 + HEAD/feed_json_created.json | 2 +- HEAD/feed_json_updated.json | 2 +- HEAD/feed_rss_created.xml | 2 +- HEAD/feed_rss_updated.xml | 2 +- HEAD/sitemap.xml | 136 +- HEAD/sitemap.xml.gz | Bin 1097 -> 1097 bytes 162 files changed, 15624 insertions(+), 489 deletions(-) create mode 100644 HEAD/api_reference/gen/assoc.qty.html create mode 100644 HEAD/api_reference/gen/derived.qty.html create mode 100644 HEAD/api_reference/gen/dimless.qty.html create mode 100644 HEAD/api_reference/gen/get.common.qty.spec.html create mode 100644 HEAD/api_reference/gen/impldefindex.html create mode 100644 HEAD/api_reference/gen/kind.of.qty.html create mode 100644 HEAD/api_reference/gen/mp.units.syns.html create mode 100644 HEAD/api_reference/gen/named.qty.html delete mode 100644 HEAD/api_reference/gen/qties.html delete mode 100644 HEAD/api_reference/gen/qties.summary.html create mode 100644 HEAD/api_reference/gen/qty.abs.pt.orig.html create mode 100644 HEAD/api_reference/gen/qty.arith.ops.html create mode 100644 HEAD/api_reference/gen/qty.assign.ops.html create mode 100644 HEAD/api_reference/gen/qty.canon.unit.html create mode 100644 HEAD/api_reference/gen/qty.char.traits.html create mode 100644 HEAD/api_reference/gen/qty.cmp.html create mode 100644 HEAD/api_reference/gen/qty.common.type.html create mode 100644 HEAD/api_reference/gen/qty.common.unit.html delete mode 100644 HEAD/api_reference/gen/qty.compat.html delete mode 100644 HEAD/api_reference/gen/qty.concepts.html create mode 100644 HEAD/api_reference/gen/qty.cons.html create mode 100644 HEAD/api_reference/gen/qty.conv.html create mode 100644 HEAD/api_reference/gen/qty.conv.ops.html create mode 100644 HEAD/api_reference/gen/qty.def.pt.orig.html create mode 100644 HEAD/api_reference/gen/qty.delta.html create mode 100644 HEAD/api_reference/gen/qty.derived.unit.html create mode 100644 HEAD/api_reference/gen/qty.dim.concepts.html create mode 100644 HEAD/api_reference/gen/qty.dim.general.html create mode 100644 HEAD/api_reference/gen/qty.dim.html create mode 100644 HEAD/api_reference/gen/qty.dim.ops.html create mode 100644 HEAD/api_reference/gen/qty.dim.sym.fmt.html create mode 100644 HEAD/api_reference/gen/qty.dim.types.html create mode 100644 HEAD/api_reference/gen/qty.fp.traits.html create mode 100644 HEAD/api_reference/gen/qty.general.html create mode 100644 HEAD/api_reference/gen/qty.get.common.base.html create mode 100644 HEAD/api_reference/gen/qty.get.kind.html delete mode 100644 HEAD/api_reference/gen/qty.helpers.html create mode 100644 HEAD/api_reference/gen/qty.html create mode 100644 HEAD/api_reference/gen/qty.imag.cpo.html create mode 100644 HEAD/api_reference/gen/qty.is.child.of.html create mode 100644 HEAD/api_reference/gen/qty.like.html create mode 100644 HEAD/api_reference/gen/qty.mag.cpo.html create mode 100644 HEAD/api_reference/gen/qty.modulus.cpo.html create mode 100644 HEAD/api_reference/gen/qty.named.unit.html create mode 100644 HEAD/api_reference/gen/qty.non.mem.conv.html create mode 100644 HEAD/api_reference/gen/qty.obs.html delete mode 100644 HEAD/api_reference/gen/qty.one.html create mode 100644 HEAD/api_reference/gen/qty.point.html delete mode 100644 HEAD/api_reference/gen/qty.point.type.html create mode 100644 HEAD/api_reference/gen/qty.prefixed.unit.html create mode 100644 HEAD/api_reference/gen/qty.pt.arith.ops.html create mode 100644 HEAD/api_reference/gen/qty.pt.assign.ops.html create mode 100644 HEAD/api_reference/gen/qty.pt.cmp.html create mode 100644 HEAD/api_reference/gen/qty.pt.cons.html create mode 100644 HEAD/api_reference/gen/qty.pt.conv.html create mode 100644 HEAD/api_reference/gen/qty.pt.conv.ops.html create mode 100644 HEAD/api_reference/gen/qty.pt.general.html create mode 100644 HEAD/api_reference/gen/qty.pt.html create mode 100644 HEAD/api_reference/gen/qty.pt.like.html create mode 100644 HEAD/api_reference/gen/qty.pt.non.mem.conv.html create mode 100644 HEAD/api_reference/gen/qty.pt.obs.html create mode 100644 HEAD/api_reference/gen/qty.pt.orig.concepts.html create mode 100644 HEAD/api_reference/gen/qty.pt.orig.general.html create mode 100644 HEAD/api_reference/gen/qty.pt.orig.html create mode 100644 HEAD/api_reference/gen/qty.pt.orig.ops.html create mode 100644 HEAD/api_reference/gen/qty.pt.orig.types.html create mode 100644 HEAD/api_reference/gen/qty.pt.orig.utils.html create mode 100644 HEAD/api_reference/gen/qty.pt.static.html create mode 100644 HEAD/api_reference/gen/qty.pt.syn.html create mode 100644 HEAD/api_reference/gen/qty.pt.unary.ops.html create mode 100644 HEAD/api_reference/gen/qty.ratio.html create mode 100644 HEAD/api_reference/gen/qty.real.cpo.html create mode 100644 HEAD/api_reference/gen/qty.ref.cmp.html create mode 100644 HEAD/api_reference/gen/qty.ref.concepts.html create mode 100644 HEAD/api_reference/gen/qty.ref.general.html create mode 100644 HEAD/api_reference/gen/qty.ref.html create mode 100644 HEAD/api_reference/gen/qty.ref.obs.html create mode 100644 HEAD/api_reference/gen/qty.ref.ops.html create mode 100644 HEAD/api_reference/gen/qty.ref.syn.html create mode 100644 HEAD/api_reference/gen/qty.rel.pt.orig.html create mode 100644 HEAD/api_reference/gen/qty.rep.concepts.html create mode 100644 HEAD/api_reference/gen/qty.rep.cpos.general.html create mode 100644 HEAD/api_reference/gen/qty.rep.cpos.html create mode 100644 HEAD/api_reference/gen/qty.rep.general.html create mode 100644 HEAD/api_reference/gen/qty.rep.html create mode 100644 HEAD/api_reference/gen/qty.rep.traits.html create mode 100644 HEAD/api_reference/gen/qty.same.abs.pt.origs.html create mode 100644 HEAD/api_reference/gen/qty.scaled.unit.html create mode 100644 HEAD/api_reference/gen/qty.spec.concepts.html create mode 100644 HEAD/api_reference/gen/qty.spec.conv.html create mode 100644 HEAD/api_reference/gen/qty.spec.general.html create mode 100644 HEAD/api_reference/gen/qty.spec.hier.algos.html create mode 100644 HEAD/api_reference/gen/qty.spec.html create mode 100644 HEAD/api_reference/gen/qty.spec.ops.html create mode 100644 HEAD/api_reference/gen/qty.spec.types.html create mode 100644 HEAD/api_reference/gen/qty.spec.utils.html create mode 100644 HEAD/api_reference/gen/qty.static.html create mode 100644 HEAD/api_reference/gen/qty.sym.expr.algos.html create mode 100644 HEAD/api_reference/gen/qty.sym.expr.concepts.html create mode 100644 HEAD/api_reference/gen/qty.sym.expr.general.html create mode 100644 HEAD/api_reference/gen/qty.sym.expr.html create mode 100644 HEAD/api_reference/gen/qty.sym.expr.types.html create mode 100644 HEAD/api_reference/gen/qty.sym.txt.html create mode 100644 HEAD/api_reference/gen/qty.syn.html delete mode 100644 HEAD/api_reference/gen/qty.traits.html delete mode 100644 HEAD/api_reference/gen/qty.type.html delete mode 100644 HEAD/api_reference/gen/qty.types.general.html delete mode 100644 HEAD/api_reference/gen/qty.types.html create mode 100644 HEAD/api_reference/gen/qty.unary.ops.html create mode 100644 HEAD/api_reference/gen/qty.unit.cmp.html create mode 100644 HEAD/api_reference/gen/qty.unit.concepts.html create mode 100644 HEAD/api_reference/gen/qty.unit.general.html create mode 100644 HEAD/api_reference/gen/qty.unit.html create mode 100644 HEAD/api_reference/gen/qty.unit.mag.concepts.html create mode 100644 HEAD/api_reference/gen/qty.unit.mag.general.html create mode 100644 HEAD/api_reference/gen/qty.unit.mag.html create mode 100644 HEAD/api_reference/gen/qty.unit.mag.ops.html create mode 100644 HEAD/api_reference/gen/qty.unit.mag.types.html create mode 100644 HEAD/api_reference/gen/qty.unit.mag.utils.html create mode 100644 HEAD/api_reference/gen/qty.unit.obs.html create mode 100644 HEAD/api_reference/gen/qty.unit.one.html create mode 100644 HEAD/api_reference/gen/qty.unit.ops.html create mode 100644 HEAD/api_reference/gen/qty.unit.sym.fmt.html create mode 100644 HEAD/api_reference/gen/qty.unit.traits.html create mode 100644 HEAD/api_reference/gen/qty.unit.types.html create mode 100644 HEAD/api_reference/gen/qty.utils.html create mode 100644 HEAD/api_reference/gen/qty.utils.non.types.html create mode 100644 HEAD/api_reference/gen/qty.val.cmp.html create mode 100644 HEAD/api_reference/gen/qty.val.traits.html create mode 100644 HEAD/api_reference/gen/qty.zeroth.pt.orig.html create mode 100644 HEAD/api_reference/gen/quantities.html create mode 100644 HEAD/api_reference/gen/quantities.summary.html delete mode 100644 HEAD/api_reference/gen/tab:qties.summary.html create mode 100644 HEAD/api_reference/gen/tab:quantities.summary.html diff --git a/HEAD/api_reference/gen/assoc.qty.html b/HEAD/api_reference/gen/assoc.qty.html new file mode 100644 index 00000000..65442c3b --- /dev/null +++ b/HEAD/api_reference/gen/assoc.qty.html @@ -0,0 +1,35 @@ +[assoc.qty]

5 Quantities and units library [quantities]

5.4 Reference [qty.ref]

5.4.4 Unit [qty.unit]

5.4.4.9 Associated quantity [assoc.qty]

template<Unit U> +consteval bool has-associated-quantity(U); // exposition only +
Returns:
  • If U​::​quantity-spec is a valid expression, +returns true.
  • Otherwise, if U​::​reference-unit is a valid expression, +returns +has-associated-quantity(U::reference-unit) +
  • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +let Nums and Dens +be packs denoting the template arguments of +U​::​nums and U​::​dens, respectively.
    Returns +(... && has-associated-quantity(expr-type<Nums>{})) && + (... && has-associated-quantity(expr-type<Dens>{})) +
  • Otherwise, returns false.
template<AssociatedUnit U> +consteval auto get-associated-quantity(U u); // exposition only +
Returns:
  • If U is of the form common_unit<Us...>, +returns +get_common_quantity_spec(get-associated-quantity(Us{})...) +
  • Otherwise, if U​::​quantity-spec is a valid expression, +returns +remove-kind(U::quantity-spec) +
  • Otherwise, if U​::​reference-unit is a valid expression, +returns +get-associated-quantity(U::reference-unit) +
  • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +returns +expr-map<to-quantity-spec, derived_quantity_spec, struct dimensionless>(u) + +where to-quantity-spec is defined as follows: +template<AssociatedUnit U> +using to-quantity-spec = decltype(get-associated-quantity(U{})); // exposition only +
\ No newline at end of file diff --git a/HEAD/api_reference/gen/conceptindex.html b/HEAD/api_reference/gen/conceptindex.html index a7f90881..54e4700d 100644 --- a/HEAD/api_reference/gen/conceptindex.html +++ b/HEAD/api_reference/gen/conceptindex.html @@ -1 +1 @@ -14882: Index of library concepts

Index of library concepts

named-quantity-spec, [qty.concepts], [qty.concepts]
some_quantity_spec, [qty.concepts]
\ No newline at end of file +14882: Index of library concepts

Index of library concepts

CommonlyInvocableQuantities, [qty.syn], [qty.syn], [qty.arith.ops]
ComplexRepresentation, [qty.rep.concepts], [qty.rep.concepts]
DimensionOf, [qty.dim.concepts]
HaveCommonReference, [qty.syn], [qty.syn]
InvocableQuantities, [qty.syn], [qty.syn], [qty.arith.ops]
IsFloatingPoint, [qty.syn], [qty.syn]
PotentiallyConvertibleTo, [qty.unit.concepts], [qty.unit.cmp]
QuantitySpecExplicitlyConvertibleTo, [qty.spec.concepts], [named.qty], [qty.spec.ops]
ScalarRepresentation, [qty.rep.concepts], [qty.rep.concepts]
VectorRepresentation, [qty.rep.concepts], [qty.rep.concepts]
\ No newline at end of file diff --git a/HEAD/api_reference/gen/defs.html b/HEAD/api_reference/gen/defs.html index 41732694..c2d03dcf 100644 --- a/HEAD/api_reference/gen/defs.html +++ b/HEAD/api_reference/gen/defs.html @@ -1,11 +1,11 @@ -[defs]

3 Terms and definitions [defs]

For the purposes of this document, +[defs]

3 Terms and definitions [defs]

For the purposes of this document, the terms and definitions given in IEC 60050-102:2007/AMD3:2021, IEC 60050-112:2010/AMD2:2020, ISO 80000-2:2019, and N4971, -and the following apply.
ISO and IEC maintain terminology databases +and the following apply.
ISO and IEC maintain terminology databases for use in standardization at the following addresses: diff --git a/HEAD/api_reference/gen/derived.qty.html b/HEAD/api_reference/gen/derived.qty.html new file mode 100644 index 00000000..30697d65 --- /dev/null +++ b/HEAD/api_reference/gen/derived.qty.html @@ -0,0 +1,38 @@ +[derived.qty]

5 Quantities and units library [quantities]

5.4 Reference [qty.ref]

5.4.3 Quantity specification [qty.spec]

5.4.3.3 Types [qty.spec.types]

5.4.3.3.2 Derived [derived.qty]

namespace mp_units { + +template<NamedQuantitySpec Q> +using to-dimension = decltype(auto(Q::dimension)); // exposition only + +template<typename... Expr> +struct derived-quantity-spec-impl : // exposition only + quantity-spec-interface, + expr-fractions<struct dimensionless, Expr...> { + using base-type = derived-quantity-spec-impl; + using base = expr-fractions<struct dimensionless, Expr...>; + + static constexpr Dimension auto dimension = + expr-map<to-dimension, derived_dimension, struct dimension_one>(base{}); + static constexpr quantity_character character = see below; +}; + +template<SymbolicConstant... Expr> +struct derived_quantity_spec final : derived-quantity-spec-impl<Expr...> {}; + +} +
derived_quantity_spec is used by the library +to represent the result of a quantity calculus not equal to a named quantity.
[Example 1: constexpr auto area = pow<2>(isq::length); +int x = area; // error: cannot construct from derived_quantity_spec<power<isq​::​length, 2>> + — end example]
+A program that instantiates a specialization of derived_quantity_spec +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
Let +
  • Nums and Dens +be packs denoting the template arguments of +base​::​nums and base​::​dens, respectively,
  • QUANTITY-CHARACTER-OF(Pack) be +std::max({quantity_character::scalar, expr-type<Pack>::character...}) + +and
  • num_char be QUANTITY-CHARACTER-OF(Nums) and +den_char be QUANTITY-CHARACTER-OF(Dens).
+The member character is equal to +quantity_character​::​scalar if num_char == den_char is true, and +std​::​max(num_char, den_char) otherwise.
\ No newline at end of file diff --git a/HEAD/api_reference/gen/dimless.qty.html b/HEAD/api_reference/gen/dimless.qty.html new file mode 100644 index 00000000..bc143772 --- /dev/null +++ b/HEAD/api_reference/gen/dimless.qty.html @@ -0,0 +1,6 @@ +[dimless.qty]

5 Quantities and units library [quantities]

5.4 Reference [qty.ref]

5.4.3 Quantity specification [qty.spec]

5.4.3.3 Types [qty.spec.types]

5.4.3.3.3 Base quantity of dimension one [dimless.qty]

namespace mp_units { + +struct dimensionless final : quantity_spec<derived_quantity_spec<>> {}; + +} +
dimensionless represents the base quantity of dimension one (IEC 60050, 112-01-13).
\ No newline at end of file diff --git a/HEAD/api_reference/gen/full.html b/HEAD/api_reference/gen/full.html index 8fc785db..2c11e6a9 100644 --- a/HEAD/api_reference/gen/full.html +++ b/HEAD/api_reference/gen/full.html @@ -1,4 +1,4 @@ -14882

1 Scope [scope]

This document describes the contents of the mp-units library.

2 References [refs]

The following documents are referred to in the text +14882

1 Scope [scope]

This document describes the contents of the mp-units library.

2 References [refs]

The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document.
For dated references, only the edition cited applies.
For undated references, the latest edition of the referenced document @@ -6,169 +6,3494 @@ the latest edition of the referenced document Amendment 3 — International Electrotechnical Vocabulary (IEV) — Part 102: Mathematics — General concepts and linear algebra
  • IEC 60050-112:2010/AMD2:2020, Amendment 2 — International Electrotechnical Vocabulary (IEV) — -Part 112: Quantities and units
  • ISO 80000 (all parts), Quantities and units
  • The C++ Standards Committee.
    N4971: Working Draft, Standard for Programming Language C++.
    Edited by Thomas Köppe.
    Available from: https://wg21.link/N4971
  • The C++ Standards Committee.
    SD-8: Standard Library Compatibility.
    Edited by Bryce Lelbach.
    Available from: https://wg21.link/SD8
  • 3 Terms and definitions [defs]

    For the purposes of this document, +Part 112: Quantities and units
  • ISO 80000 (all parts), Quantities and units
  • The C++ Standards Committee.
    N4971: Working Draft, Standard for Programming Language C++.
    Edited by Thomas Köppe.
    Available from: https://wg21.link/N4971
  • The C++ Standards Committee.
    P3094R5: std​::​basic_fixed_string.
    Edited by Mateusz Pusz.
  • The C++ Standards Committee.
    SD-8: Standard Library Compatibility.
    Edited by Bryce Lelbach.
    Available from: https://wg21.link/SD8
  • 3 Terms and definitions [defs]

    For the purposes of this document, the terms and definitions given in IEC 60050-102:2007/AMD3:2021, IEC 60050-112:2010/AMD2:2020, ISO 80000-2:2019, and N4971, -and the following apply.
    ISO and IEC maintain terminology databases +and the following apply.
    ISO and IEC maintain terminology databases for use in standardization at the following addresses: -

    4 Specification [spec]

    4.1 External [spec.ext]

    The specification of the mp-units library subsumes +

    4 Specification [spec]

    4.1 External [spec.ext]

    The specification of the mp-units library subsumes N4971, [description], N4971, [requirements], N4971, [concepts.equality], and SD-8, all assumingly amended for the context of this library.
    [Note 1: 
    This means that, non exhaustively,
    • ​::​mp_units2 is a reserved namespace, and
    • std​::​vector<mp_units​::​type> is a program-defined specialization and a library-defined specialization -from the point of view of the C++ standard library and the mp-units library, respectively.
    — end note]
    The mp-units library is not part of the C++ implementation.

    4.2 Categories [spec.cats]

    Detailed specifications for each of the components in the library are in -[qties]–[qties], -as shown in Table 1.
    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    The quantities library ([qties]) -describes components for dealing with quantities.

    4.3 Modules [spec.mods]

    The mp-units library provides the +from the point of view of the C++ standard library and the mp-units library, respectively.
    — end note]
    The mp-units library is not part of the C++ implementation.

    4.2 Categories [spec.cats]

    Detailed specifications for each of the components in the library are in +[quantities]–[quantities], +as shown in Table 1.
    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    The quantities library ([quantities]) +describes components for dealing with quantities.

    4.3 Modules [spec.mods]

    The mp-units library provides the mp-units modules, -shown in Table 2.
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with -MP_UNITSdigit-sequence_.

    5 Quantities library [qties]

    5.1 Summary [qties.summary]

    This Clause describes components for dealing with quantities, -as summarized in Table 3.
    Table 3: Quantities library summary [tab:qties.summary]
    Subclause
    Module
    Helpers
    mp_units.core
    Traits
    Concepts
    Types
    Compatibility
    Dimension one
    Systems
    mp_units.systems
    std​::​chrono compatibility

    5.2 Module mp_units synopsis [mp.units.syn]

    export module mp_units; +shown in Table 2.
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with +MP_UNITSdigit-sequence_.

    5 Quantities and units library [quantities]

    5.1 Summary [quantities.summary]

    This Clause describes components for dealing with quantities and units, +as summarized in Table 3.
    Table 3: Quantities and units library summary [tab:quantities.summary]
    Subclause
    Module
    Utilities
    mp_units.core
    Reference
    Representation
    Quantity
    Quantity point
    Systems
    mp_units.systems
    std​::​chrono interoperability
    +
    [Editor's note: +Following the SG16 recommendation at https://lists.isocpp.org/sg16/2024/10/4490.php, +the universal-character-names should be replaced by their UTF-8 code points. +]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.1 Module mp_units synopsis [mp.units.syn]

    export module mp_units; export import mp_units.core; export import mp_units.systems; -

    5.3 Module mp_units.core synopsis [mp.units.core.syn]

    export module mp_units.core; +

    5.2.2 Module mp_units.core synopsis [mp.units.core.syn]

    // mostly freestanding +export module mp_units.core; import std; export namespace mp_units { -export enum class quantity_character { scalar, vector, tensor }; +// [qty.utils], utilities -// [qty.traits], traits +// [qty.sym.txt], symbol text -template<typename Rep> -constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>; +enum class character_set : std::int8_t { utf8, portable, default_character_set = utf8 }; -template<typename Rep> -constexpr bool is_scalar = - std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>); +template<std::size_t N, std::size_t M> +class symbol_text; -template<typename Rep> -constexpr bool is_vector = false; +// [qty.sym.expr], symbolic expressions -template<typename Rep> -constexpr bool is_tensor = false; +// [qty.sym.expr.types], types -template<typename Rep> -struct quantity_values; +template<typename T, typename... Ts> +struct per; + +template<typename F, int Num, int... Den> + requires see below +struct power; + +// [qty.ref], reference + +// [qty.dim], dimension + +// [qty.dim.concepts], concepts template<typename T> -struct quantity_like_traits; +concept Dimension = see below; + +template<typename T, auto D> +concept DimensionOf = see below; + +// [qty.dim.types], types + +template<symbol_text Symbol> +struct base_dimension; + +template<SymbolicConstant... Expr> +struct derived_dimension; + +struct dimension_one; +inline constexpr dimension_one dimension_one{}; + +// [qty.dim.ops], operations + +consteval Dimension auto inverse(Dimension auto d); + +template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +consteval Dimension auto sqrt(Dimension auto d); +consteval Dimension auto cbrt(Dimension auto d); + +// [qty.dim.sym.fmt], symbol formatting + +struct dimension_symbol_formatting { + character_set char_set = character_set::default_character_set; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); + +template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); + +// [qty.spec], quantity specification + +// [qty.spec.concepts], concepts template<typename T> -struct quantity_point_like_traits; +concept QuantitySpec = see below; -// [qty.concepts], concepts +template<typename T, auto QS> +concept QuantitySpecOf = see below; -template<typename T> -concept some_reference = template_of(^std::remove_cvref_t<T>) == ^reference; +// [qty.spec.types], types -template<typename T> -concept representation = see below; +// [named.qty], named -template<typename T, quantity_character Ch> -concept representation_of = see below; - -template<typename T> -concept some_quantity_spec = see below; - -// [qty.types], types +struct is_kind; +inline constexpr is_kind is_kind{}; template<auto...> -struct quantity_spec; // not defined +struct quantity_spec; // not defined -template<auto Q> -struct kind_of_; // not defined +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...>; -template<unspecified... Expr> +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...>; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...>; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<QS, Eq, Args...>; + +// [derived.qty], derived + +template<SymbolicConstant... Expr> struct derived_quantity_spec; -// [qty.type], class template quantity -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> -class quantity; +// [dimless.qty], base quantity of dimension one -// [qty.point.type], class template quantity_point -template<unspecified> -class quantity_point; +struct dimensionless; +inline constexpr dimensionless dimensionless{}; + +// [kind.of.qty], kind of + +template<QuantitySpec Q> + requires see below +struct kind_of_; +template<QuantitySpec auto Q> + requires requires { typename kind_of_<decltype(Q)>; } +inline constexpr kind_of_<decltype(Q)> kind_of{}; + +// [qty.spec.ops], operations + +consteval QuantitySpec auto inverse(QuantitySpec auto q); + +template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +consteval QuantitySpec auto sqrt(QuantitySpec auto q); +consteval QuantitySpec auto cbrt(QuantitySpec auto q); + +// [qty.spec.hier.algos], hierarchy algorithms + +// [qty.spec.conv], conversion + +consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); + +// [qty.get.kind], get_kind + +template<QuantitySpec Q> +consteval see below get_kind(Q); + +// [get.common.qty.spec], get_common_quantity_spec + +consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; + +// [qty.unit], unit + +// [qty.unit.mag], magnitude + +// [qty.unit.mag.concepts], concepts + +template<typename T> +concept MagConstant = see below; + +template<typename T> +concept UnitMagnitude = see below; + +// [qty.unit.mag.types], types + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant; + +// [qty.unit.mag.ops], operations + +template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; + +template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; + +template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = see below; + +// constants + +inline constexpr struct pi final : + mag_constant<{u8"\u03C0" /* U+03c0 GREEK SMALL LETTER PI */, "pi"}, + std::numbers::pi_v<long double>> { +} pi; + +inline constexpr auto \u03C0 /* U+03c0 GREEK SMALL LETTER PI */ = pi; + +// [qty.unit.traits], traits + +template<Unit auto U> +constexpr bool space_before_unit_symbol = true; + +template<> +inline constexpr bool space_before_unit_symbol<one> = false; + +// [qty.unit.concepts], concepts + +template<typename T> +concept Unit = see below; + +template<typename T> +concept PrefixableUnit = see below; + +template<typename T> +concept AssociatedUnit = see below; + +template<typename U, auto QS> +concept UnitOf = see below; + +// [qty.unit.types], types + +// [qty.scaled.unit], scaled + +template<UnitMagnitude auto M, Unit U> + requires see below +struct scaled_unit; + +// [qty.named.unit], named + +template<symbol_text Symbol, auto...> +struct named_unit; // not defined + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, QS>; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, QS, PO>; + +template<symbol_text Symbol> + requires see below +struct named_unit<Symbol>; + +template<symbol_text Symbol, Unit auto U> + requires see below +struct named_unit<Symbol, U>; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, PO>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, U, QS>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, QS, PO>; + +// [qty.prefixed.unit], prefixed + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires see below +struct prefixed_unit; + +// [qty.common.unit], common + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit; + +// [qty.derived.unit], derived + +template<SymbolicConstant... Expr> +struct derived_unit; + +// [qty.unit.one], one + +struct one; +inline constexpr one one{}; + +// named derived units of a quantity of dimension one + +inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> { +} percent; + +inline constexpr struct per_mille final : + named_unit<symbol_text{u8"\u2030" /* U+2030 PER MILLE SIGN */, "%o"}, + mag_ratio<1, 1000> * one> { +} per_mille; + +inline constexpr struct parts_per_million final : + named_unit<"ppm", mag_ratio<1, 1'000'000> * one> { +} parts_per_million; + +inline constexpr auto ppm = parts_per_million; + +// [qty.unit.ops], operations + +consteval Unit auto inverse(Unit auto u); + +template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires see below +consteval Unit auto pow(U u); +consteval Unit auto sqrt(Unit auto u); +consteval Unit auto cbrt(Unit auto u); +consteval Unit auto square(Unit auto u); +consteval Unit auto cubic(Unit auto u); + +// [qty.unit.cmp], comparison + +template<Unit From, Unit To> +consteval bool convertible(From from, To to); + +// [qty.unit.obs], observers + +consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +consteval Unit auto get_unit(AssociatedUnit auto u); + +consteval Unit auto get_common_unit(Unit auto... us) + requires see below; + +// [qty.unit.sym.fmt], symbol formatting + +enum class unit_symbol_solidus : std::int8_t { + one_denominator, + always, + never, + default_denominator = one_denominator +}; + +enum class unit_symbol_separator : std::int8_t { + space, + half_high_dot, + default_separator = space +}; + +struct unit_symbol_formatting { + character_set char_set = character_set::default_character_set; + unit_symbol_solidus solidus = unit_symbol_solidus::default_denominator; + unit_symbol_separator separator = unit_symbol_separator::default_separator; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); + +template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); + +// [qty.ref.concepts], concepts + +template<typename T> +concept Reference = see below; + +template<typename T, auto QS> +concept ReferenceOf = see below; + +// [qty.ref.syn], class template reference + +template<QuantitySpec Q, Unit U> +struct reference; + +// [qty.ref.ops], operations + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; + +// [qty.ref.obs], observers + +template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); + +template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); + +consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; + +template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; + +// [qty.rep], representation + +enum class quantity_character { scalar, complex, vector, tensor }; + +// [qty.rep.traits], traits + +// [qty.fp.traits], floating-point + +template<typename Rep> +constexpr bool treat_as_floating_point = see below; + +// [qty.char.traits], quantity character + +template<typename T> +constexpr bool disable_scalar = false; +template<> +inline constexpr bool disable_scalar<bool> = true; +template<typename T> +constexpr bool disable_scalar<std::complex<T>> = true; + +template<typename T> +constexpr bool disable_complex = false; + +template<typename T> +constexpr bool disable_vector = false; + +// [qty.val.traits], values + +template<typename Rep> +struct representation_values; + +// [qty.rep.cpos], customization point objects + +inline namespace unspecified { + +inline constexpr unspecified real = unspecified; +inline constexpr unspecified imag = unspecified; +inline constexpr unspecified modulus = unspecified; + +inline constexpr unspecified magnitude = unspecified; } -

    5.4 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; + +// [qty.rep.concepts], concepts + +template<typename T> +concept Representation = see below; + +template<typename T, quantity_character Ch> +concept RepresentationOf = see below; + +// [qty], quantity + +// [qty.like], interoperability + +template<typename T> +struct quantity_like_traits; // not defined + +template<typename T> +concept QuantityLike = see below; + +// [qty.syn], class template quantity + +template<typename T> +concept Quantity = see below; + +template<typename Q, auto QS> +concept QuantityOf = see below; + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity; + +// [qty.delta], construction helper delta + +template<Reference R> +struct delta_; + +template<Reference auto R> +constexpr delta_<decltype(R)> delta{}; + +// [qty.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Representation ToRep, see below> + requires see below +constexpr quantity<see below, ToRep> value_cast(see below q); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr Quantity auto value_cast(see below q); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Quantity ToQ, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr Quantity auto quantity_cast(see below q); + +} + +// [qty.common.type], std​::​common_type specializations + +template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires see below +struct std::common_type<Q1, Q2>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires see below +struct std::common_type<Q, Value>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires requires { typename std::common_type<Q, Value>; } +struct std::common_type<Value, Q> : std::common_type<Q, Value> {}; + +namespace mp_units { + +// [qty.pt], quantity point + +// [qty.pt.orig], point origin + +// [qty.pt.orig.concepts], concepts + +template<typename T> +concept PointOrigin = see below; + +template<typename T, auto QS> +concept PointOriginFor = see below; + +// [qty.pt.orig.types], types + +// [qty.abs.pt.orig], absolute + +template<QuantitySpec auto QS> +struct absolute_point_origin; + +// [qty.rel.pt.orig], relative + +template<QuantityPoint auto QP> +struct relative_point_origin; + +// [qty.zeroth.pt.orig], zeroth + +template<QuantitySpec auto QS> +struct zeroth_point_origin_; + +template<QuantitySpec auto QS> +constexpr zeroth_point_origin_<QS> zeroth_point_origin{}; + +// [qty.def.pt.orig], default + +template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); + +// [qty.pt.like], interoperability + +template<typename T> +struct quantity_point_like_traits; // not defined + +template<typename T> +concept QuantityPointLike = see below; + +// [qty.pt.syn], class template quantity_point + +template<typename T> +concept QuantityPoint = see below; + +template<typename QP, auto V> +concept QuantityPointOf = see below; + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point; + +// [qty.point], construction helper point + +template<Reference R> +struct point_; + +template<Reference auto R> +constexpr point_<decltype(R)> point{}; + +// [qty.pt.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Representation ToRep, see below> + requires see below +constexpr quantity_point<see below, see below, ToRep> value_cast(see below qp); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Quantity ToQ, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantityPoint ToQP, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr QuantityPoint auto quantity_cast(see below qp); + +} +

    5.2.3 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; export import mp_units.core; import std; export namespace mp_units { +// [qty.chrono], std​::​chrono interoperability + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>>; + +template<typename Clock> +struct chrono_point_origin_; +template<typename Clock> +constexpr chrono_point_origin_<Clock> chrono_point_origin{}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>>; + } -

    5.5 Helpers [qty.helpers]

    consteval bool converts-to-base-subobject-of(std::meta type, std::meta template_name); -
    Preconditions: is_type(type) && is_template(template_name) is true.
    Returns: true if -[:type:] has an unambiguous and accessible base -that is a specialization of [:template_name:], and -false otherwise.

    5.6 Traits [qty.traits]

    template<typename Rep> -constexpr bool is_scalar = - std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>); +

    5.3 Utilities [qty.utils]

    5.3.1 Non-types [qty.utils.non.types]

    template<typename T, template<see below> typename U> +consteval bool is-specialization-of(); // exposition only +template<typename T, template<see below> typename U> +consteval bool is-derived-from-specialization-of(); // exposition only +
    Returns:
    • For the first signature, +true of T is a specialization of U, and +false otherwise.
    • For the second signature, +true if T has exactly one public base class +that is a specialization of U +and has no other base class that is a specialization of U, and +false otherwise.
    Remarks: An implementation provides enough overloads for all arguments to U.

    5.3.2 Ratio [qty.ratio]

    namespace mp_units { -template<typename Rep> -constexpr bool is_vector = false; +struct ratio { // exposition only + std::intmax_t num; + std::intmax_t den; -template<typename Rep> -constexpr bool is_tensor = false; -
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), -users may specialize is_scalar, is_vector, and is_tensor to true -for cv-unqualified program-defined types -which respectively represent -a scalar (IEC 60050, 102-02-18), -a vector (IEC 60050, 102-03-04), and -a tensor, -and false for types which respectively do not.

    5.7 Concepts [qty.concepts]

    export template<typename T> -concept representation = - (is_scalar<T> || is_vector<T> || is_tensor<T>)&&std::regular<T> && scalable<T>; -
    export template<typename T, quantity_character Ch> -concept representation_of = - representation<T> && ((Ch == quantity_character::scalar && is_scalar<T>) || - (Ch == quantity_character::vector && is_vector<T>) || - (Ch == quantity_character::tensor && is_tensor<T>)); -
    template<typename T> -concept named-quantity-spec = - (converts-to-base-subobject-of(^T, ^quantity_spec) && template_of(^T) != ^kind_of_); + consteval ratio(std::intmax_t n, std::intmax_t d = 1); + + friend consteval bool operator==(ratio, ratio) = default; + friend consteval auto operator<=>(ratio lhs, ratio rhs) { return (lhs - rhs).num <=> 0; } + + friend consteval ratio operator-(ratio r) { return {-r.num, r.den}; } + + friend consteval ratio operator+(ratio lhs, ratio rhs) + { + return {lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den}; + } + + friend consteval ratio operator-(ratio lhs, ratio rhs) { return lhs + (-rhs); } + + friend consteval ratio operator*(ratio lhs, ratio rhs); + + friend consteval ratio operator/(ratio lhs, ratio rhs) + { + return lhs * ratio{rhs.den, rhs.num}; + } +}; + +consteval bool is-integral(ratio r) { return r.num % r.den == 0; } + +consteval ratio common-ratio(ratio r1, ratio r2); + +} +
    ratio represents the rational number .
    Unless otherwise specified, +in the following descriptions, +let R(r) be std​::​ratio<N, D>, +where N and D are the values of r.num and r.den.
    consteval ratio(std::intmax_t n, std::intmax_t d = 1); +
    Let N and D be the values of n and d.
    Let R be std​::​ratio<N, D>.
    Effects: Equivalent to +R.
    Postconditions: num == R​::​num && den == R​::​den is true.
    friend consteval ratio operator*(ratio lhs, ratio rhs); +
    Let Res be std​::​ratio_multiply<R(lhs), R(rhs)>.
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};
    consteval ratio common-ratio(ratio r1, ratio r2); +
    Let Res be equal to +std::common_type<std::chrono::duration<int, R(r1)>, + std::chrono::duration<int, R(r2)>>::type::period +
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};

    5.3.3 Symbol text [qty.sym.txt]

    namespace mp_units { + +template<std::size_t N, std::size_t M> +class symbol_text { +public: + std::fixed_u8string<N> utf8; // exposition only + std::fixed_string<M> portable; // exposition only + + // constructors + constexpr symbol_text(char portable); + consteval symbol_text(const char (&portable)[N + 1]); + constexpr symbol_text(const std::fixed_string<N>& portable); + consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); + constexpr symbol_text(const std::fixed_u8string<N>& utf8, + const std::fixed_string<M>& portable); + + // observers + constexpr const auto& utf8() const { return utf8; } + constexpr const auto& portable() const { return portable; } + constexpr bool empty() const { return utf8().empty(); } + + // string operations + template<std::size_t N2, std::size_t M2> + friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); + + // comparison + template<std::size_t N2, std::size_t M2> + friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; + template<std::size_t N2, std::size_t M2> + friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +}; + +symbol_text(char) -> symbol_text<1, 1>; + +template<std::size_t N> +symbol_text(const char (&)[N]) -> symbol_text<N - 1, N - 1>; + +template<std::size_t N> +symbol_text(const std::fixed_string<N>&) -> symbol_text<N, N>; + +template<std::size_t N, std::size_t M> +symbol_text(const char8_t (&)[N], const char (&)[M]) -> symbol_text<N - 1, M - 1>; + +template<std::size_t N, std::size_t M> +symbol_text(const std::fixed_u8string<N>&, const std::fixed_string<M>&) -> symbol_text<N, M>; + +} +
    symbol_text represents a symbol text.
    utf8 stores its UTF-8 representation, and +portable stores its portable representation.
    symbol_text<N, M> is a structural type (N4971, [temp.param]).
    In the descriptions that follow, +it is a Precondition that +
    • values of char are in the basic literal character set (N4971, [lex.charset]), and
    • for a parameter of the form const CharT (&txt)[M], +(txt[M - 1] == CharT()) is true.
    constexpr symbol_text(char portable); +consteval symbol_text(const char (&portable)[N + 1]); +constexpr symbol_text(const std::fixed_string<N>& portable); +consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); +constexpr symbol_text(const std::fixed_u8string<N>& utf8, const std::fixed_string<M>& portable); +
    For the constructors without a parameter named utf8, +let utf8 be: +std::bit_cast<std::fixed_u8string<N>>(std::basic_fixed_string(portable)) +
    Effects: Equivalent to the mem-initializer-list: +utf8{utf8}, portable{portable} +
    template<std::size_t N2, std::size_t M2> +friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); +
    Effects: Equivalent to: +return symbol_text<N + N2, M + M2>(lhs.utf8() + rhs.utf8(), + lhs.portable() + rhs.portable()); +
    template<std::size_t N2, std::size_t M2> +friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +template<std::size_t N2, std::size_t M2> +friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +
    Let @ be the operator.
    Effects: Equivalent to: +return std::make_tuple(std::cref(lhs.utf8()), std::cref(lhs.portable())) @ + std::make_tuple(std::cref(rhs.utf8()), std::cref(rhs.portable())); +

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.1 General [qty.sym.expr.general]

    Subclause [qty.sym.expr] specifies the components +used to maintain ordered, simplified, and readable +argument lists in the names of specializations.
    [Example 1: using namespace si::unit_symbols; +int x = kg * km / square(h); // error: cannot construct from + // derived_unit<si​::​kilo_<si​::​gram>, si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>> +
    +The library ensures decltype(kg * km / square(h)) is styled-like as commented in diagnostics, +provided that, in the implementation-defined total order of types, +decltype(kg) is less than decltype(km).
    — end example]

    5.3.4.2 Concept SymbolicConstant [qty.sym.expr.concepts]

    template<typename T> +concept SymbolicConstant = // exposition only + std::is_empty_v<T> && std::is_final_v<T> && std::is_trivially_default_constructible_v<T> && + std::is_trivially_copy_constructible_v<T> && std::is_trivially_move_constructible_v<T> && + std::is_trivially_destructible_v<T>; +
    The concept SymbolicConstant +is used to constrain the types +that are used in symbolic expressions.

    5.3.4.3 Types [qty.sym.expr.types]

    namespace mp_units { + +template<typename T, typename... Ts> +struct per final {}; + +} +
    per is used to store arguments with negative exponents.
    A specialization of per +represents the product of the inverse of its template arguments.
    A program that instantiates a specialization of per +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +template<typename F, int Num, int... Den> + requires see below +struct power final { + using factor = F; // exposition only + static constexpr ratio exponent{Num, Den...}; // exposition only +}; + +} +
    power represents a power (IEC 60050, 102-02-08) +of the form .
    [Note 1: 
    Den is optional to shorten the type name when Den is 1.
    — end note]
    +A program that instantiates a specialization of power +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let r be ratio{Num, Den...}.
    Let is-valid-ratio be +true if r is a valid constant expression, and +false otherwise.
    The expression in the requires-clause is equivalent to: +is-valid-ratio && (r > ratio{0}) && (r != ratio{1}) +

    5.3.4.4 Algorithms [qty.sym.expr.algos]

    template<typename T> +using expr-type = see below; // exposition only +
    expr-type<T> denotes +U if T is of the form power<U, Ints...>, and +T otherwise.
    template<typename T, typename U> +consteval bool type-less-impl(); // exposition only +
    Returns: true if T is less than U +in an implementation-defined total order for types, and +false otherwise.
    template<typename Lhs, typename Rhs> +struct type-less : // exposition only + std::bool_constant<is-specialization-of<Rhs, power>() || + type-less-impl<expr-type<Lhs>, expr-type<Rhs>>()> {}; +
    type-less meets the requirements of +the Pred parameter of the symbolic expression algorithms below.
    template<typename... Ts> +struct type-list {}; // exposition only + +template<typename OneType, typename... Ts> +struct expr-fractions { // exposition only + using num = see below; // exposition only + using den = see below; // exposition only +} +
    expr-fractions divides a symbolic expression to numerator and denominator parts.
    Let EF be a specialization of expr-fractions.
    • If EF is of the form expr-fractions<OneType, Ts..., per<Us...>>, +then +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<Us...>.
    • Otherwise, EF is of the form expr-fractions<OneType, Ts...>, and +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<>.
    The symbolic expression algorithms perform operations on symbolic constants.
    A symbolic constant is a type that is a model of SymbolicConstant.
    [Example 1: 
    The dimension dim_length, the quantity time, and the unit one are symbolic constants.
    — end example]
    +The algorithms also support +powers with a symbolic constant base and a rational exponent, +products thereof, and +fractions thereof.
    template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-multiply(Lhs, Rhs); // exposition only + +template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-divide(Lhs lhs, Rhs rhs); // exposition only + +template<template<typename...> typename To, typename OneType, typename T> +consteval auto expr-invert(T); // exposition only + +template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, + typename OneType, template<typename, typename> typename Pred = type-less, typename T> + requires(Den != 0) +consteval auto expr-pow(T); // exposition only +
    Mandates:
    • OneType is the neutral element (IEC 60050, 102-01-19) of the operation, and
    • Pred is a Cpp17BinaryTypeTrait (N4971, [meta.rqmts]) +with a base characteristic of std​::​bool_constant<B>.
      Pred<T, U> implements a total order for types; +B is true if T is ordered before U, and false otherwise.
    Effects:
    First, inputs to the operations are obtained from the types of the function parameters.
    If the type of a function parameter is: +
    • A specialization of To, +then its input is the product of its template arguments, and +the following also apply.
    • A specialization of per, +then its input is the product of the inverse of its template arguments, and +the following also apply.
    • A specialization of the form power<F, Num>, +then its input is , or +a specialization of the form power<F, Num, Den>, +then its input is , and +the following also applies.
    • Otherwise, the input is the symbolic constant itself.
    [Example 2: 
    Item by item, this algorithm step goes from the C++ parameter type +decltype(km / square(h)), +styled in diagnostics like +derived_unit<si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>, +
    • to decltype(km) ×per<power<decltype(h), 2> (product of To's arguments),
    • to (product of inverse of per's arguments),
    • to (powers as powers),
    • to where and (symbolic substitution) +in the mathematical domain.
    — end example]
    Then, the operation takes place: +
    • expr-multiply multiplies its inputs,
    • expr-divide divides the input of its first parameter by the input of its second parameter,
    • expr-invert divides 1 by its input, and
    • expr-pow raises its input to the .
    Finally, let r be the result of the operation simplified as follows: +
    • All terms are part of the same fraction (if any).
    • There is at most a single term with a given symbolic constant.
    • There are no negative exponents.
    • 1 is only present as r and as a numerator with a denominator not equal to 1.
    [Example 3: 
    Item by item:

    (single fraction)
    (unique symbolic constants)
    (positive exponents)
    (non-redundant 1s)
    — end example]
    Returns: r is mapped to the return type: +
    • If , returns OneType{}.
    • Otherwise, if r is a symbolic constant, returns r.
    • Otherwise, first applies the following mappings to the terms of r: +
      • is mapped to power<x, n, d>, and + is mapped to power<x, n>, and
      • 1 is mapped to OneType{}.
    • Then, a denominator x of r (if any) is mapped to per<x>.
    • Then, sorts r without per (if any) and +the template arguments of per (if any) +according to Pred.
    • Finally, returns To<r>{}, where per (if any) is the last argument.
    Remarks: A valid template argument list for To and per +is formed by interspersing commas between each mapped term.
    If a mapping to std​::​intmax_t is not representable, +the program is ill-formed.
    expr-map maps the contents of one symbolic expression to another resulting in a different type list.
    template<template<typename> typename Proj, template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename T> +consteval auto expr-map(T); // exposition only +
    Let +
    • expr-type-map<U> be +power<Proj<F>, Ints...> if U is of the form power<F, Ints...>, and +Proj<U> otherwise,
    • map-power(u) be +pow<Ints...>(F{}) if decltype(u) is of the form power<F, Ints...>, and +u otherwise, and
    • Nums and Dens +be packs denoting the template arguments of +T​::​nums and T​::​dens, respectively.
    Returns: (OneType{} * ... * map-power(expr-type-map<Nums>{})) / +(OneType{} * ... * map-power(expr-type-map<Dens>{})) +

    5.4 Reference [qty.ref]

    5.4.1 General [qty.ref.general]

    Subclause [qty.ref] specifies the components +for describing the reference of a quantity (IEC 60050, 112-01-01).

    5.4.2 Dimension [qty.dim]

    5.4.2.1 General [qty.dim.general]

    Subclause [qty.dim] specifies the components +for defining the dimension of a quantity (IEC 60050, 112-01-11).

    5.4.2.2 Concepts [qty.dim.concepts]

    template<typename T> +concept Dimension = SymbolicConstant<T> && std::derived_from<T, dimension-interface>; template<typename T> -concept some_quantity_spec = - named-quantity-spec<T> || - detail::IntermediateDerivedQuantitySpec<T> || - template_of(^T) == ^kind_of; -

    5.8 Types [qty.types]

    5.8.1 General [qty.types.general]

    A quantity type -is a type Q -that is a specialization of quantity or quantity_point.
    Q represents a quantity (IEC 60050, 112-01-01) -with Q​::​rep as its number -and Q​::​reference as its reference.
    Q is a structural type (N4971, [temp.param]) -if Q​::​rep is a structural type.
    Each class template defined in subclause [qty.types] -has data members and special members specified below, and -has no base classes or members other than those specified.

    5.8.2 Class template quantity [qty.type]

    namespace mp_units { +concept BaseDimension = // exposition only + Dimension<T> && (is-derived-from-specialization-of<T, base_dimension>()); -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> -class quantity { unspecified }; +template<typename T, auto D> +concept DimensionOf = Dimension<T> && Dimension<decltype(D)> && (T{} == D); +

    5.4.2.3 Types [qty.dim.types]

    namespace mp_units { + +template<symbol_text Symbol> +struct base_dimension : dimension-interface { + static constexpr auto symbol = Symbol; // exposition only +}; } -
    Let Q be a specialization of quantity.

    5.8.3 Class template quantity_point [qty.point.type]

    namespace mp_units { +
    base_dimension is used +to define the dimension of a base quantity (IEC 60050, 112-01-08).
    Symbol is its symbolic representation.
    [Example 1: inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length; + — end example]
    namespace mp_units { -export template<unspecified> -class quantity_point { unspecified }; +template<typename... Expr> +struct derived-dimension-impl // exposition only + : expr-fractions<struct dimension_one, Expr...> {}; + +template<SymbolicConstant... Expr> +struct derived_dimension final : dimension-interface, derived-dimension-impl<Expr...> {}; } -
    A quantity point type is a specialization of quantity_point.
    Let Q be a quantity point type.
    Q​::​point_origin represents -the origin point of a position vector (IEC 60050, 102-03-15).
    • If Rep is a scalar, -Q represents the scalar quantity (IEC 60050, 102-02-19) -of a position vector.
    • If Rep is a vector, -Q represents a position vector.

    5.9 Compatibility [qty.compat]

    5.10 Dimension one [qty.one]

    5.12 std​::​chrono compatibility [qty.chrono]

    \ No newline at end of file +
    derived_dimension is used by the library +to represent the dimension of a derived quantity (IEC 60050, 112-01-10).
    [Example 2: constexpr auto dim_acceleration = isq::speed.dimension / isq::dim_time; +int x = dim_acceleration; // error: cannot construct from + // derived_dimension<isq​::​dim_length, per<power<isq​::​dim_time, 2>>> + — end example]
    +A program that instantiates a specialization of derived_dimension +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +struct dimension_one final : dimension-interface, derived-dimension-impl<> {}; + +} +
    dimension_one represents the dimension of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.2.4 Operations [qty.dim.ops]

    namespace mp_units { + +struct dimension-interface { // exposition only + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator*(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator/(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator*(Lhs, Rhs); +
    Returns: expr-multiply<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator/(Lhs, Rhs); +
    Returns: expr-divide<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval Dimension auto inverse(Dimension auto d); +
    Returns: dimension_one / d.
    template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +
    Returns: expr-pow<Num, Den, derived_dimension, struct dimension_one>(d).
    consteval Dimension auto sqrt(Dimension auto d); +
    Returns: pow<1, 2>(d).
    consteval Dimension auto cbrt(Dimension auto d); +
    Returns: pow<1, 3>(d).

    5.4.2.5 Symbol formatting [qty.dim.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); +
    Effects: Equivalent to: +TBD. +

    5.4.3 Quantity specification [qty.spec]

    5.4.3.1 General [qty.spec.general]

    Subclause [qty.spec] specifies the components +for defining a quantity (IEC 60050, 112-01-01).

    5.4.3.2 Concepts [qty.spec.concepts]

    template<typename T> +concept QuantitySpec = SymbolicConstant<T> && std::derived_from<T, quantity-spec-interface>; + +template<typename T> +concept QuantityKindSpec = // exposition only + QuantitySpec<T> && is-specialization-of<T, kind_of_>(); + +template<typename T> +concept NamedQuantitySpec = // exposition only + QuantitySpec<T> && is-derived-from-specialization-of<T, quantity_spec>() && + (!QuantityKindSpec<T>); + +template<typename T> +concept DerivedQuantitySpec = // exposition only + QuantitySpec<T> && + (is-specialization-of<T, derived_quantity_spec>() || + (QuantityKindSpec<T> && + is-specialization-of<decltype(auto(T::quantity-spec)), derived_quantity_spec>())); + +template<auto Child, auto Parent> +concept ChildQuantitySpecOf = (is-child-of(Child, Parent)); // exposition only + +template<auto To, auto From> +concept NestedQuantityKindSpecOf = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && + (get_kind(From) != get_kind(To)) && ChildQuantitySpecOf<To, get_kind(From).quantity-spec>; + +template<auto From, auto To> +concept QuantitySpecConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && implicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecExplicitlyConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && explicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecCastableTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && castable(From, To); + +template<typename T, auto QS> +concept QuantitySpecOf = + QuantitySpec<T> && QuantitySpec<decltype(QS)> && QuantitySpecConvertibleTo<T{}, QS> && + !NestedQuantityKindSpecOf<T{}, QS> && + (QuantityKindSpec<T> || !NestedQuantityKindSpecOf<QS, T{}>); + +template<typename T> +concept QSProperty = (!QuantitySpec<T>); // exposition only +

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.1 Named [named.qty]

    namespace mp_units { + +struct is_kind {}; + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr BaseDimension auto dimension = Dim; + static constexpr quantity_character character = see below; +}; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = parent.equation; // exposition only, present only + // if the qualified-id parent.equation is valid and denotes an object + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> + requires QuantitySpecExplicitlyConvertibleTo<Eq, QS> +struct quantity_spec<QS, Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +} +
    A named quantity is a type that models NamedQuantitySpec.
    A specialization of quantity_spec is used as a base type when defining a named quantity.
    In the following descriptions, let Q be a named quantity defined with an alluded signature.
    The identifier of Q represents its quantity name (IEC 60050, 112-01-02).
    Let Ch be an enumerator value of quantity_character.
    The possible arguments to quantity_spec are +
    • ,
    • ,
    • , and
    • .
    If the first argument is a base quantity dimension, +then Q is that base quantity (IEC 60050, 112-01-08).
    If an argument is a quantity calculus (IEC 60050, 112-01-30) C, +then Q is implicitly convertible from C.
    If the first argument is a named quantity, +then Q is of its kind (IEC 60050, 112-01-04).
    The member character represents +the set of the numerical value of Q ([qty.char.traits]) +and is equal to +
    • Ch if specified,
    • otherwise, quantity_character​::​scalar for the first signature, and
    • otherwise, (BC).character, +where BC is the argument preceding Ch in the signatures above.
    is_kind specifies Q to start a new hierarchy tree of a kind.
    Optional arguments may appear in any order.
    [Example 1: // The first signature defines a base quantity. +inline constexpr struct length final : quantity_spec<dim_length> { +} length; // Length is a base quantity. + +// The second signature defines a derived quantity. +inline constexpr struct area final : quantity_spec<pow<2>(length)> { +} area; // An area equals length by length. + +// The third and fourth signatures add a leaf to a hierarchy of kinds. +inline constexpr struct width final : quantity_spec<length> { +} width; // Width is a kind of length. + +// The fourth signature also refines the calculus required for implicit conversions. +inline constexpr struct angular_measure final : + quantity_spec<dimensionless, arc_length / radius, is_kind> { +} angular_measure; // Requires an arc length per radius, not just any quantity of dimension one. + — end example]

    5.4.3.3.2 Derived [derived.qty]

    namespace mp_units { + +template<NamedQuantitySpec Q> +using to-dimension = decltype(auto(Q::dimension)); // exposition only + +template<typename... Expr> +struct derived-quantity-spec-impl : // exposition only + quantity-spec-interface, + expr-fractions<struct dimensionless, Expr...> { + using base-type = derived-quantity-spec-impl; + using base = expr-fractions<struct dimensionless, Expr...>; + + static constexpr Dimension auto dimension = + expr-map<to-dimension, derived_dimension, struct dimension_one>(base{}); + static constexpr quantity_character character = see below; +}; + +template<SymbolicConstant... Expr> +struct derived_quantity_spec final : derived-quantity-spec-impl<Expr...> {}; + +} +
    derived_quantity_spec is used by the library +to represent the result of a quantity calculus not equal to a named quantity.
    [Example 1: constexpr auto area = pow<2>(isq::length); +int x = area; // error: cannot construct from derived_quantity_spec<power<isq​::​length, 2>> + — end example]
    +A program that instantiates a specialization of derived_quantity_spec +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let +
    • Nums and Dens +be packs denoting the template arguments of +base​::​nums and base​::​dens, respectively,
    • QUANTITY-CHARACTER-OF(Pack) be +std::max({quantity_character::scalar, expr-type<Pack>::character...}) + +and
    • num_char be QUANTITY-CHARACTER-OF(Nums) and +den_char be QUANTITY-CHARACTER-OF(Dens).
    +The member character is equal to +quantity_character​::​scalar if num_char == den_char is true, and +std​::​max(num_char, den_char) otherwise.

    5.4.3.3.3 Base quantity of dimension one [dimless.qty]

    namespace mp_units { + +struct dimensionless final : quantity_spec<derived_quantity_spec<>> {}; + +} +
    dimensionless represents the base quantity of dimension one (IEC 60050, 112-01-13).

    5.4.3.3.4 Kind of [kind.of.qty]

    namespace mp_units { + +template<QuantitySpec Q> + requires(!QuantityKindSpec<Q>) && (get-kind-tree-root(Q{}) == Q{}) +struct kind_of_ final : Q::base-type { + using base-type = kind_of_; // exposition only + static constexpr auto quantity-spec = Q{}; // exposition only +}; + +} +
    kind_of<Q> represents a kind of quantity (IEC 60050, 112-01-04) Q.

    5.4.3.4 Utilities [qty.spec.utils]

    template<QuantitySpec auto... From, QuantitySpec Q> +consteval QuantitySpec auto clone-kind-of(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr ((... && QuantityKindSpec<decltype(From)>)) + return kind_of<Q{}>; +else + return q; +
    template<QuantitySpec Q> +consteval auto remove-kind(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr (QuantityKindSpec<Q>) + return Q::quantity-spec; +else + return q; +
    template<QuantitySpec QS, Unit U> + requires(!AssociatedUnit<U>) || UnitOf<U, QS{}> +consteval Reference auto make-reference(QS, U u); // exposition only +
    Effects: Equivalent to: +if constexpr (requires { requires get_quantity_spec(U{}) == QS{}; }) + return u; +else + return reference<QS, U>{}; +

    5.4.3.5 Operations [qty.spec.ops]

    namespace mp_units { + +struct quantity-spec-interface { // exposition only + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); + + template<typename Self, UnitOf<Self{}> U> + consteval Reference auto operator[](this Self self, U u); + + template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> + constexpr Quantity auto operator()(this Self self, FwdQ&& q); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-multiply<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-divide<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<typename Self, UnitOf<Self{}> U> +consteval Reference auto operator[](this Self self, U u); +
    Returns: make-reference(self, u).
    template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> +constexpr Quantity auto operator()(this Self self, FwdQ&& q); +
    Returns: quantity{std::forward<FwdQ>(q).numerical-value, make-reference(self, Q::unit)} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval QuantitySpec auto inverse(QuantitySpec auto q); +
    Returns: dimensionless / q.
    template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +
    Returns: clone-kind-of<Q{}>( + expr-pow<Num, Den, derived_quantity_spec, struct dimensionless>(remove-kind(q))); +
    consteval QuantitySpec auto sqrt(QuantitySpec auto q); +
    Returns: pow<1, 2>(q).
    consteval QuantitySpec auto cbrt(QuantitySpec auto q); +
    Returns: pow<1, 3>(q).

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.1 Conversion [qty.spec.conv]

    consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); +
    Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).

    5.4.3.6.2 Get kind [qty.get.kind]

    template<QuantitySpec Q> +consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only +
    Returns:
    • If QuantityKindSpec<Q> is true, +returns remove-kind(q).
    • Otherwise, if +is-derived-from-specialization-of<Q, quantity_spec>() +is true, and +the specialization of Q​::​quantity_spec has a template argument equal to is_kind, +returns q.
    • Otherwise, if Q​::​parent is a valid expression, +returns get-kind-tree-root(Q​::​parent).
    • Otherwise, if DerivedQuantitySpec<Q> is true, +returns +expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) + +where to-kind is defined as follows: +template<QuantitySpec Q> +using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only +
    • Otherwise, returns q.
    template<QuantitySpec Q> +consteval QuantityKindSpec auto get_kind(Q); +
    Returns: kind_of<get-kind-tree-root(Q{})>.

    5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

    consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; +
    Let +
    • q1 be qs...[0],
    • q2 be qs...[1],
    • Q1 be decltype(q1),
    • Q2 be decltype(q2), and
    • rest be a pack denoting the elements of qs without q1 and q2.
    Effects: Equivalent to: +if constexpr (sizeof...(qs) == 1) + return q1; +else if constexpr (sizeof...(qs) == 2) { + using QQ1 = decltype(remove-kind(q1)); + using QQ2 = decltype(remove-kind(q2)); + + if constexpr (std::is_same_v<Q1, Q2>) + return q1; + else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) + return QQ1{}; + else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) + return QQ2{}; + else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || + (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && + implicitly_convertible(Q1{}, Q2{}))) + return q2; + else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || + (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && + implicitly_convertible(Q2{}, Q1{}))) + return q1; + else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) + return *common_base; + else if constexpr (implicitly_convertible(Q1{}, Q2{})) + return q2; + else if constexpr (implicitly_convertible(Q2{}, Q1{})) + return q1; + else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), + get-kind-tree-root(Q2{}))) + return get-kind-tree-root(q2); + else + return get-kind-tree-root(q1); +} else + return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(qs) != 0 && + (sizeof...(qs) == 1 || + (sizeof...(qs) == 2 && + (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || + QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || + requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); })) +

    5.4.3.6.4 Get common base [qty.get.common.base]

    In this subclause and [qty.is.child.of], +let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple +, +where par is parent.
    template<QuantitySpec auto A, QuantitySpec auto B> +consteval auto get-common-base(); // exposition only +
    Let +
    • be the number of elements in h(A),
    • be the number of elements in h(B),
    • s be ,
    • A be a tuple of the last s elements of h(A), and
    • B be a tuple of the last s elements of h(B).
    Effects: Looks for x, the first pair-wise equal element in A and B.
    Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.

    5.4.3.6.5 Is child of [qty.is.child.of]

    template<QuantitySpec Child, QuantitySpec Parent> +consteval bool is-child-of(Child ch, Parent p); // exposition only +
    Returns: If h(p) has more elements than h(ch), returns false.
    Otherwise, let C be a tuple of the last s elements of h(ch), +where s is the number of elements in h(p).
    Returns == p.

    5.4.4 Unit [qty.unit]

    5.4.4.1 General [qty.unit.general]

    Subclause [qty.unit] specifies the components +for defining a unit of measurement (IEC 60050, 112-01-14).

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.1 General [qty.unit.mag.general]

    Subclause [qty.unit.mag] specifies the components +used to represent the numerical value (IEC 60050, 112-01-29) of a unit +with support for powers (IEC 60050, 102-02-08) of real numbers (IEC 60050, 102-02-05).

    5.4.4.2.2 Concepts [qty.unit.mag.concepts]

    template<typename T> +concept MagConstant = SymbolicConstant<T> && is-derived-from-specialization-of<T, mag_constant>(); + +template<typename T> +concept UnitMagnitude = (is-specialization-of<T, unit-magnitude>()); + +template<typename T> +concept MagArg = std::integral<T> || MagConstant<T>; // exposition only +

    5.4.4.2.3 Types [qty.unit.mag.types]

    namespace mp_units { + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant { + static constexpr auto symbol = Symbol; // exposition only + static constexpr long double value = Value; // exposition only +}; + +} +
    A specialization of mag_constant represents a real number (IEC 60050, 102-02-05).
    Symbol is its symbol, and +Value is (an approximation of) its value.
    namespace mp_units { + +template<auto... Ms> +struct unit-magnitude { // exposition only + // [qty.unit.mag.ops], operations + + template<UnitMagnitude M> + friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); + + friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); + + template<UnitMagnitude Rhs> + friend consteval bool operator==(unit-magnitude, Rhs); + + template<int Num, int Den = 1> + friend consteval auto pow(unit-magnitude); // exposition only + + // [qty.unit.mag.utils], utilities + + friend consteval bool is-positive-integral-power(unit-magnitude); // exposition only + + template<auto... Ms2> + friend consteval auto common-magnitude(unit-magnitude, // exposition only + unit-magnitude<Ms2...>); +}; + +} +
    A specialization of unit-magnitude +represents the product of its template arguments.
    For the purposes of specifying the implementation-defined limits, +let the representation of the terms of unit-magnitude be the structure +struct { + ratio exp; + base-type base; +}; + +representing the number , +where base-type is a model of MagArg.
    • There is a single term for each base-type.
    • exp.num is not expanded into base.
      [Note 1: 
      is not permitted.
      — end note]
    • exp.den can reduce the base.
      [Note 2: 
      is permitted.
      — end note]
    • If the result of an operation on std​::​intmax_t values is undefined, +the behavior is +implementation-defined.

    5.4.4.2.4 Operations [qty.unit.mag.ops]

    template<UnitMagnitude M> +friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); +
    Returns:
    • If sizeof...(Ms) == 0 is true, returns rhs.
    • Otherwise, if std​::​is_same_v<M, unit-magnitude<>>, returns lhs.
    • Otherwise, returns an unspecified value equal to lhs ×rhs.
    friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); +
    Returns: lhs * pow<-1>(rhs).
    template<UnitMagnitude Rhs> +friend consteval bool operator==(unit-magnitude, Rhs); +
    Returns: std​::​is_same_v<unit-magnitude, Rhs>.
    template<int Num, int Den = 1> +friend consteval auto pow(unit-magnitude base); // exposition only +
    Returns:
    • If Num == 0 is true, returns unit-magnitude<>{}.
    • Otherwise, returns an unspecified value equal to .
    template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; +
    Constraints: V is greater than 0.
    Effects: If MagConstant<decltype(V)> is satisfied, +initializes mag with unit-magnitude<V>{}.
    Otherwise, initializes mag with +an unspecified value equal to V.
    template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; +
    Effects: Initializes mag_ratio with +an unspecified value equal to .
    template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = pow<Num, Den>(mag<Base>); +
    Constraints: Base is greater than 0.

    5.4.4.2.5 Utilities [qty.unit.mag.utils]

    friend consteval bool is-positive-integral-power(unit-magnitude x); // exposition only +
    Returns: false if x has a negative or rational exponent, and +true otherwise.
    template<auto... Ms2> +friend consteval auto common-magnitude(unit-magnitude, unit-magnitude<Ms2...>); // exposition only +
    Returns: The largest magnitude C +such that each input magnitude is expressible +by only positive powers relative to C.

    5.4.4.3 Traits [qty.unit.traits]

    template<Unit auto U> +constexpr bool space_before_unit_symbol = true; +
    The formatting functions ([qty.unit.sym.fmt]) use space_before_unit_symbol +to determine whether there is a space +between the numerical value and the unit symbol.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize space_before_unit_symbol +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.4.4.4 Concepts [qty.unit.concepts]

    template<typename T> +concept Unit = SymbolicConstant<T> && std::derived_from<T, unit-interface>; + +template<typename T> +concept PrefixableUnit = Unit<T> && is-derived-from-specialization-of<T, named_unit>(); + +template<typename T> +concept AssociatedUnit = Unit<U> && has-associated-quantity(U{}); + +template<typename U, auto QS> +concept UnitOf = AssociatedUnit<U> && QuantitySpec<decltype(QS)> && + QuantitySpecConvertibleTo<get_quantity_spec(U{}), QS> && + (get_kind(QS) == get_kind(get_quantity_spec(U{})) || + !NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>); + +template<auto From, auto To> +concept UnitConvertibleTo = // exposition only + Unit<decltype(From)> && Unit<decltype(To)> && (convertible(From, To)); + +template<typename U, auto FromU, auto QS> +concept UnitCompatibleWith = // exposition only + Unit<U> && Unit<decltype(FromU)> && QuantitySpec<decltype(QS)> && + (!AssociatedUnit<U> || UnitOf<U, QS>) && UnitConvertibleTo<FromU, U{}>; + +template<typename T> +concept OffsetUnit = Unit<T> && requires { T::point-origin; }; // exposition only + +template<typename From, typename To> +concept PotentiallyConvertibleTo = // exposition only + Unit<From> && Unit<To> && + ((AssociatedUnit<From> && AssociatedUnit<To> && + implicitly_convertible(get_quantity_spec(From{}), get_quantity_spec(To{}))) || + (!AssociatedUnit<From> && !AssociatedUnit<To>)); +

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.1 Canonical [qty.canon.unit]

    namespace mp_units { + +template<UnitMagnitude M, Unit U> +struct canonical-unit { // exposition only + M mag; + U reference_unit; +}; + +} +
    canonical-unit represents a unit expressed in terms of base units (IEC 60050, 112-01-18).
    [Note 1: 
    Other types representing units are equal only if they have the same type.
    canonical-unit is used to implement binary relations other than equality.
    — end note]
    reference_unit is simplified ([qty.sym.expr.algos]).
    consteval auto get-canonical-unit(Unit auto u); // exposition only +
    Returns: The instantiation of canonical-unit for u.

    5.4.4.5.2 Scaled [qty.scaled.unit]

    namespace mp_units { + +template<UnitMagnitude auto M, Unit U> + requires(M != unit-magnitude<>{} && M != mag<1>) +struct scaled_unit final : unit-interface { + using base-type = scaled_unit; // exposition only + static constexpr UnitMagnitude auto mag = M; // exposition only + static constexpr U reference-unit{}; // exposition only + static constexpr auto point-origin = U::point_origin; // exposition only, present only + // if the qualified-id U​::​point_origin is valid and denotes an object +}; + +} +
    scaled_unit<M, U> is used by the library +to represent the unit M ×U.

    5.4.4.5.3 Named [qty.named.unit]

    namespace mp_units { + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS, PO> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol> + requires(!Symbol.empty()) +struct named_unit<Symbol> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U> + requires(!Symbol.empty()) +struct named_unit<Symbol, U> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires(!Symbol.empty()) +struct named_unit<Symbol, U, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +} +
    A named unit is a type that models PrefixableUnit.
    A specialization of named_unit is used as a base type when defining a named unit.
    In the following descriptions, let U be a named unit defined with an alluded signature.
    The identifier of U represents +its unit name (IEC 60050, 112-01-15) +or special unit name (IEC 60050, 112-01-16).
    Symbol is its unit symbol (IEC 60050, 112-01-17).
    The possible arguments to named_unit are +
    • ,
    • ,
    • , and
    • .
    The first signature defines the unit of a base quantity +without a unit prefix (IEC 60050, 112-01-26).
    The second signature defines a unit +that can be reused by several base quantities.
    The third and fourth signatures with a unit expression argument E +define U as implicitly convertible from E.
    The first and fourth signatures with a kind of quantity (IEC 60050, 112-01-04) Q +also restrict U to Q.
    A point origin argument specifies the default point origin of U ([qty.pt.syn]).
    [Example 1: // 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; // . + +// The fourth signature also further restricts the kind of quantity. +inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { +} hertz; // Hz can't measure becquerel, activity, + // or any other quantity with dimension + // that isn't a kind of frequency. + — end example]

    5.4.4.5.4 Prefixed [qty.prefixed.unit]

    namespace mp_units { + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires(!Symbol.empty()) +struct prefixed_unit : decltype(M * U)::base-type { + using base-type = prefixed_unit; // exposition only + static constexpr auto symbol = Symbol + U.symbol; // exposition only +}; + +} +
    prefixed_unit<Symbol, M, U> represents the unit U with a unit prefix (IEC 60050, 112-01-26).
    Symbol is the symbol of the unit prefix.
    M is the factor of the unit prefix.
    A specialization of prefixed_unit is used as a base type when defining a unit prefix.
    [Example 1: template<PrefixableUnit auto U> +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + +template<PrefixableUnit auto U> +constexpr kilo_<U> kilo; + +inline constexpr auto kilogram = kilo<si::gram>; + — end example]

    5.4.4.5.5 Common [qty.common.unit]

    namespace mp_units { + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit final : decltype(get-common-scaled-unit(U1{}, U2{}, Rest{}...))::base-type +{ + using base-type = common_unit; // exposition only + static constexpr auto common-unit = // exposition only + get-common-scaled-unit(U1{}, U2{}, Rest{}...); +}; + +} +
    common_unit is used by the library +to encapsulate a conversion factor between units (IEC 60050, 112-01-33) +common to the operands of quantity addition.
    [Example 1: 
    The result of 1 * km + 1 * mi +has a common unit +encapsulated by common_unit<mi, km>.
    — end example]
    +A program that instantiates a specialization of common_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    template<Unit U1, Unit U2, Unit... Rest> +consteval Unit auto get-common-scaled-unit(U1, U2, Rest... rest) // exposition only + requires see below; +
    Effects: Equivalent to: +constexpr auto res = [] { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + constexpr auto common_mag = common-magnitude(canonical_lhs.mag, canonical_rhs.mag); + if constexpr (common_mag == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit<common_mag, decltype(auto(canonical_lhs.reference_unit))>{}; +}(); +if constexpr (sizeof...(rest) == 0) + return res; +else + return get-common-scaled-unit(res, rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(U1{}, U2{}) && (sizeof...(Rest) == 0 || requires { + get-common-scaled-unit(get-common-scaled-unit(u1, u2), rest...); + })) +

    5.4.4.5.6 Derived [qty.derived.unit]

    namespace mp_units { + +template<typename... Expr> +struct derived-unit-impl : // exposition only + unit-interface, + expr-fractions<struct one, Expr...> { + using base-type = derived-unit-impl; // exposition only +}; + +template<SymbolicConstant... Expr> +struct derived_unit final : derived-unit-impl<Expr...> {}; + +} +
    derived_unit is used by the library +to represent a derived unit (IEC 60050, 112-01-19).
    [Example 1: using namespace si::unit_symbols; +int x = m * m; // error: cannot construct from derived_unit<power<si​::​metre, 2>> +int y = m * s; // error: cannot construct from derived_unit<si​::​metre, si​::​second> +int z = m / s; // error: cannot construct from derived_unit<si​::​metre, per<si​::​second>> + — end example]
    +A program that instantiates a specialization of derived_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.

    5.4.4.5.7 One [qty.unit.one]

    namespace mp_units { + +struct one final : derived-unit-impl<> {}; + +} +
    one represents the base unit (IEC 60050, 112-01-18) of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.4.6 Operations [qty.unit.ops]

    namespace mp_units { + +struct unit-interface { // exposition only + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator*(M, U u); + + friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; + + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator/(M mag, U u); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); + + // [qty.unit.cmp], comparison + + template<Unit Lhs, Unit Rhs> + friend consteval bool operator==(Lhs, Rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval bool equivalent(Lhs lhs, Rhs rhs); +}; + +} +
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator*(M, U u); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<M, decltype(auto(mag<1>))>) + return u; +else if constexpr (is-specialization-of<U, scaled_unit>()) { + if constexpr (M{} * U::mag == mag<1>) + return U::reference-unit; + else + return scaled_unit<M{} * U::mag, decltype(auto(U::reference-unit))>{}; +} else + return scaled_unit<M{}, U>{}; +
    friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; +
    Recommended practice: Suggest swapping the operands.
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator/(M mag, U u); +
    Returns: mag * inverse(u).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); +
    Returns: expr-multiply<derived_unit, struct one>(lhs, rhs).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); +
    Returns: expr-divide<derived_unit, struct one>(lhs, rhs).
    consteval Unit auto inverse(Unit auto u); +
    Returns: one / u.
    template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires(Den != 0) +consteval Unit auto pow(U u); +
    Returns: expr-pow<Num, Den, derived_unit, struct one>(u).
    consteval Unit auto sqrt(Unit auto u); +
    Returns: pow<1, 2>(u).
    consteval Unit auto cbrt(Unit auto u); +
    Returns: pow<1, 3>(u).
    consteval Unit auto square(Unit auto u); +
    Returns: pow<2>(u).
    consteval Unit auto cubic(Unit auto u); +
    Returns: pow<3>(u).

    5.4.4.7 Comparison [qty.unit.cmp]

    template<Unit Lhs, Unit Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    template<Unit Lhs, Unit Rhs> +friend consteval bool equivalent(Lhs lhs, Rhs rhs); +
    Effects: Equivalent to: +const auto lhs_canonical = get-canonical-unit(lhs); +const auto rhs_canonical = get-canonical-unit(rhs); +return lhs_canonical.mag == rhs_canonical.mag && + lhs_canonical.reference_unit == rhs_canonical.reference_unit; +
    template<Unit From, Unit To> +consteval bool convertible(From from, To to); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<From, To>) + return true; +else if constexpr (PotentiallyConvertibleTo<From, To>) + return std::is_same_v<decltype(get-canonical-unit(from).reference_unit), + decltype(get-canonical-unit(to).reference_unit)>; +else + return false; +

    5.4.4.8 Observers [qty.unit.obs]

    consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +
    Returns: kind_of<get-associated-quantity(u)>.
    consteval Unit auto get_unit(AssociatedUnit auto u); +
    Returns: u.
    consteval Unit auto get_common_unit(Unit auto... us) + requires see below; +
    Let +
    • u1 be us...[0],
    • u2 be us...[1],
    • U1 be decltype(u1),
    • U2 be decltype(u2), and
    • rest be a pack denoting the elements of us without u1 and u2.
    Effects: Equivalent to: +if constexpr (sizeof...(us) == 1) + return u1; +else if constexpr (sizeof...(us) == 2) { + if constexpr (is-derived-from-specialization-of<U1, common_unit>()) { + return TBD.; + } else if constexpr (is-derived-from-specialization-of<U2, common_unit>()) + return get_common_unit(u2, u1); + else if constexpr (std::is_same_v<U1, U2>) + return u1; + else if constexpr (equivalent(U1{}, U2{})) { + if constexpr (std::derived_from<U1, typename U2::base-type>) + return u1; + else if constexpr (std::derived_from<U2, typename U1::base-type>) + return u2; + else + return std::conditional_t<type-less-impl<U1, U2>(), U1, U2>{}; + } else { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + + if constexpr (is-positive-integral-power(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is-positive-integral-power(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + if constexpr (type-less<U1, U2>{}) + return common_unit<U1, U2>{}; + else + return common_unit<U2, U1>{}; + } + } +} else + return get_common_unit(get_common_unit(u1, u2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(us) != 0 && (sizeof...(us) == 1 || // + (sizeof...(us) == 2 && convertible(U1{}, U2{})) || + requires { get_common_unit(get_common_unit(u1, u2), rest...); })) +

    5.4.4.9 Associated quantity [assoc.qty]

    template<Unit U> +consteval bool has-associated-quantity(U); // exposition only +
    Returns:
    • If U​::​quantity-spec is a valid expression, +returns true.
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +has-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +let Nums and Dens +be packs denoting the template arguments of +U​::​nums and U​::​dens, respectively.
      Returns +(... && has-associated-quantity(expr-type<Nums>{})) && + (... && has-associated-quantity(expr-type<Dens>{})) +
    • Otherwise, returns false.
    template<AssociatedUnit U> +consteval auto get-associated-quantity(U u); // exposition only +
    Returns:
    • If U is of the form common_unit<Us...>, +returns +get_common_quantity_spec(get-associated-quantity(Us{})...) +
    • Otherwise, if U​::​quantity-spec is a valid expression, +returns +remove-kind(U::quantity-spec) +
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +get-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +returns +expr-map<to-quantity-spec, derived_quantity_spec, struct dimensionless>(u) + +where to-quantity-spec is defined as follows: +template<AssociatedUnit U> +using to-quantity-spec = decltype(get-associated-quantity(U{})); // exposition only +

    5.4.4.10 Symbol formatting [qty.unit.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); +
    Effects: Equivalent to: +TBD. +

    5.4.5 Concepts [qty.ref.concepts]

    template<typename T> +concept Reference = AssociatedUnit<T> || (is-specialization-of<T, reference>()); +
    A type T that satisfies Reference +represents the reference of a quantity (IEC 60050, 112-01-01).
    template<typename T, auto QS> +concept ReferenceOf = Reference<T> && QuantitySpecOf<decltype(get_quantity_spec(T{})), QS>; +

    5.4.6 Class template reference [qty.ref.syn]

    namespace mp_units { + +template<QuantitySpec auto Q, Unit auto U> +using reference-t = reference<decltype(Q), decltype(U)>; // exposition only + +template<QuantitySpec Q, Unit U> +struct reference { + // [qty.ref.ops], operations + + template<typename Q2, typename U2> + friend consteval auto operator*(reference, reference<Q2, U2>) + -> reference-t<Q{} * Q2{}, U{} * U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator*(reference, U2) + -> reference-t<Q{} * get_quantity_spec(U2{}), U{} * U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator*(U1, reference) + -> reference-t<get_quantity_spec(U1{}) * Q{}, U1{} * U{}>; + + template<typename Q2, typename U2> + friend consteval auto operator/(reference, reference<Q2, U2>) + -> reference-t<Q{} / Q2{}, U{} / U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator/(reference, U2) + -> reference-t<Q{} / get_quantity_spec(U2{}), U{} / U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator/(U1, reference) + -> reference-t<get_quantity_spec(U1{}) / Q{}, U1{} / U{}>; + + friend consteval auto inverse(reference) -> reference-t<inverse(Q{}), inverse(U{})>; + + template<std::intmax_t Num, std::intmax_t Den = 1> + requires(Den != 0) + friend consteval auto pow(reference) -> reference-t<pow<Num, Den>(Q{}), pow<Num, Den>(U{})>; + friend consteval auto sqrt(reference) -> reference-t<sqrt(Q{}), sqrt(U{})>; + friend consteval auto cbrt(reference) -> reference-t<cbrt(Q{}), cbrt(U{})>; + + // [qty.ref.cmp], comparison + + template<typename Q2, typename U2> + friend consteval bool operator==(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool operator==(reference, U2 u2); + + template<typename Q2, typename U2> + friend consteval bool convertible(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool convertible(reference, U2 u2); + + template<AssociatedUnit U1> + friend consteval bool convertible(U1 u1, reference); +}; + +} +
    reference<Q, U> represents the reference of a quantity (IEC 60050, 112-01-01).
    The unit of measurement U (IEC 60050, 112-01-14) +is used to measure a value of the quantity Q (IEC 60050, 112-01-28).
    [Note 1: 
    reference is typically implicitly instantiated +when specifying that a unit measures a more specific quantity.
    [Example 1: using namespace si::unit_symbols; +auto x = 1 * m; // measures a length +auto y = 1 * isq::width[m]; // measures a width +auto z = 1 * isq::diameter[m]; // measures a diameter + — end example]
    — end note]

    5.4.7 Operations [qty.ref.ops]

    Each member function with a trailing-return-type +of -> reference-t<T...> +returns {}.
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), r};
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), inverse(R{})};
    template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); +
    Let @ be the operator.
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, Q::reference @ R{}}; +
    template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; +
    Recommended practice: Suggest swapping the operands.

    5.4.8 Comparison [qty.ref.cmp]

    template<typename Q2, typename U2> +friend consteval bool operator==(reference, reference<Q2, U2>); +
    Returns: Q{} == Q2{} && U{} == U2{}.
    template<AssociatedUnit U2> +friend consteval bool operator==(reference, U2 u2); +
    Returns: Q{} == get_quantity_spec(u2) && U{} == u2.
    template<typename Q2, typename U2> +friend consteval bool convertible(reference, reference<Q2, U2>); +
    Returns: implicitly_convertible(Q{}, Q2{}) && convertible(U{}, U2{}).
    template<AssociatedUnit U2> +friend consteval bool convertible(reference, U2 u2); +
    Returns: implicitly_convertible(Q{}, get_quantity_spec(u2)) && convertible(U{}, u2).
    template<AssociatedUnit U1> +friend consteval bool convertible(U1 u1, reference); +
    Returns: implicitly_convertible(get_quantity_spec(u1), Q{}) && convertible(u1, U{}).

    5.4.9 Observers [qty.ref.obs]

    template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); +
    Returns: Q{}.
    template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); +
    Returns: U{}.
    consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; +
    Returns: get_common_unit(u1, u2, rest...).
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), + get_quantity_spec(rest)...); + { get_common_unit(u1, u2, rest...) } -> AssociatedUnit; +} +
    template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; +
    Returns: reference-t<get_common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}), + get_quantity_spec(rest)...), + get_common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), + get_quantity_spec(rest)...); + get_common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...); +} +

    5.5 Representation [qty.rep]

    5.5.1 General [qty.rep.general]

    Subclause [qty.rep] specifies the components +used to constrain the numerical value of a quantity (IEC 60050, 112-01-29).

    5.5.2 Traits [qty.rep.traits]

    5.5.2.1 Floating-point [qty.fp.traits]

    template<typename T> +struct actual-value-type : cond-value-type<T> {}; // see N4971, [readable.traits] + +template<typename T> + requires(!std::is_pointer_v<T> && !std::is_array_v<T>) && + requires { typename std::indirectly_readable_traits<T>::value_type; } +struct actual-value-type<T> : std::indirectly_readable_traits<T> {}; + +template<typename T> +using actual-value-type-t = actual-value-type<T>::value_type; + +template<typename Rep> +constexpr bool treat_as_floating_point = + std::chrono::treat_as_floating_point_v<actual-value-type-t<Rep>>; +
    quantity and quantity_point use treat_as_floating_point +to help determine whether implicit conversions are allowed among them.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize treat_as_floating_point +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.5.2.2 Quantity character [qty.char.traits]

    template<typename T> +constexpr bool disable_scalar = false; +template<typename T> +constexpr bool disable_complex = false; +template<typename T> +constexpr bool disable_vector = false; +
    Some quantities are defined as having a numerical value (IEC 60050, 112-01-29) of a specific set (IEC 60050, 102-01-02).
    The representation concepts use these traits +to help determine the sets T represents.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize these templates +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    [Note 1: 
    These templates prevent use of representation types with the library +that satisfy but do not in fact model their corresponding concept.
    — end note]

    5.5.2.3 Values [qty.val.traits]

    quantity and quantity_point use representation_values +to construct special values of its representation type.
    namespace mp_units { + +template<typename Rep> +struct representation_values : std::chrono::duration_values<Rep> { + static constexpr Rep one() noexcept; +}; + +} +
    The requirements on std​::​chrono​::​duration_values<Rep> (N4971, [time.traits.duration.values]) +also apply to representation_values<Rep>.
    static constexpr Rep one() noexcept; +
    Returns: Rep(1).
    Remarks: The value returned shall be the neutral element for multiplication (IEC 60050, 102-01-19).

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    The name mp_units​::​real denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​real(E) is ill-formed.
    • If auto(t.real()) is a valid expression whose type models Scalar, +mp_units​::​real(E) is expression-equivalent to auto(t.real()).
    • Otherwise, if T is a class or enumeration type and +auto(real(t)) is a valid expression whose type models Scalar +where the meaning of real is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​real(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​real(E) is ill-formed.

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    The name mp_units​::​imag denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​imag(E) is ill-formed.
    • If auto(t.imag()) is a valid expression whose type models Scalar, +mp_units​::​imag(E) is expression-equivalent to auto(t.imag()).
    • Otherwise, if T is a class or enumeration type and +auto(imag(t)) is a valid expression whose type models Scalar +where the meaning of imag is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​imag(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​imag(E) is ill-formed.

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    The name mp_units​::​modulus denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​modulus(E) is ill-formed.
    • If auto(t.modulus()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.modulus()).
    • Otherwise, if T is a class or enumeration type and +auto(modulus(t)) is a valid expression whose type models Scalar +where the meaning of modulus is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • If auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of abs is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​modulus(E) is ill-formed.

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    The name mp_units​::​magnitude denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​magnitude(E) is ill-formed.
    • If auto(t.magnitude()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(E) is expression-equivalent to auto(t.magnitude()).
    • Otherwise, if T is a class or enumeration type and +auto(magnitude(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, if auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(​E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​magnitude(E) is ill-formed.

    5.5.4 Concepts [qty.rep.concepts]

    template<typename T> +concept WeaklyRegular = std::copyable<T> && std::equality_comparable<T>; // exposition only + +template<typename T> +concept Scalar = (!disable_scalar<T>) && WeaklyRegular<T> && requires(T a, T b) { // exposition only + // 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>; +}; +
    TBD.
    template<typename T> +using value-type-t = actual-value-type-t<T>; // exposition only, see [qty.fp.traits] + +template<typename T> +concept Complex = // exposition only + (!disable_complex<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + std::constructible_from<T, value-type-t<T>, value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +concept Vector = // exposition only + (!disable_vector<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +using scaling-factor-type-t = // exposition only + std::conditional_t<treat_as_floating_point<T>, long double, std::intmax_t>; + +template<typename T> +concept ScalarRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Scalar<T> && + requires(T a, T b, 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>; + }; +
    TBD.
    template<typename T> +concept ComplexRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Complex<T> && + requires(T a, T b, scaling-factor-type-t<T> f) { + // scaling + { a * T(f) } -> std::common_with<T>; + { T(f) * a } -> std::common_with<T>; + { a / T(f) } -> std::common_with<T>; + }; +
    TBD.
    template<typename T> +concept VectorRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Vector<T>; +
    TBD.
    template<typename T> +concept Representation = ScalarRepresentation<T> || ComplexRepresentation<T> || + VectorRepresentation<T>; +
    A type T models Representation if +it represents the numerical value of a quantity (IEC 60050, 112-01-29).
    template<typename T, quantity_character Ch> +concept IsOfCharacter = (Ch == quantity_character::scalar && Scalar<T>) || // exposition only + (Ch == quantity_character::complex && Complex<T>) || + (Ch == quantity_character::vector && Vector<T>); + +template<typename T, auto V> +concept RepresentationOf = + Representation<T> && ((QuantitySpec<decltype(V)> && + (QuantityKindSpec<decltype(V)> || IsOfCharacter<T, V.character>)) || + (std::same_as<quantity_character, decltype(V)> && IsOfCharacter<T, V>)); +
    A type T models RepresentationOf<V> if +T models Representation and +
    • V is a kind of quantity, or
    • if V is a quantity, then T represents a value of its character, or
    • if V is a quantity character, then T represents a value of V.

    5.6 Quantity [qty]

    5.6.1 General [qty.general]

    Subclause [qty] describes the class template quantity +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of a vector space (IEC 60050, 102-03-01,102-03-04).

    5.6.2 Interoperability [qty.like]

    The interfaces specified in this subclause and subclause [qty.pt.like] +are used by quantity and quantity_point +to specify conversions with other types representing quantities.
    [Note 1: 
    [qty.chrono] implements them for std​::​chrono​::​duration and std​::​chrono​::​time_point.
    — end note]
    template<typename T, template<typename> typename Traits> +concept qty-like-impl = requires(const T& qty, const Traits<T>::rep& num) { // exposition only + { Traits<T>::to_numerical_value(qty) } -> std::same_as<typename Traits<T>::rep>; + { Traits<T>::from_numerical_value(num) } -> std::same_as<T>; + requires std::same_as<decltype(Traits<T>::explicit_import), const bool>; + requires std::same_as<decltype(Traits<T>::explicit_export), const bool>; + typename std::bool_constant<Traits<T>::explicit_import>; + typename std::bool_constant<Traits<T>::explicit_export>; +}; + +template<typename T> +concept QuantityLike = !Quantity<T> && qty-like-impl<T, quantity_like_traits> && requires { + typename quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; +}; +
    In the following descriptions, let +
    • Traits be quantity_like_traits or quantity_point_like_traits,
    • Q be a type for which Traits<Q> is specialized,
    • qty be an lvalue of type const Q, and
    • num be an lvalue of type const Traits<Q>​::​rep.
    Q models qty-like-impl<Traits> if and only if: +
    • Traits<Q>​::​to_numerical_value(qty) returns the numerical value (IEC 60050, 112-01-29) of qty.
    • Traits<Q>​::​from_numerical_value(num) returns a Q with numerical value num.
    • If Traits is quantity_point_like_traits, +both numerical values are offset from Traits<Q>​::​point_origin.
    If the following expression is true, the specified conversion will be explicit.
    • Traits<Q>​::​explicit_import for the conversion from Q to this library's type.
    • Traits<Q>​::​explicit_export for the conversion from this library's type to Q.

    5.6.3 Class template quantity [qty.syn]

    namespace mp_units { + +template<typename T> +concept Quantity = (is-derived-from-specialization-of<T, quantity>()); // exposition only + +template<typename Q, auto QS> +concept QuantityOf = // exposition only + Quantity<Q> && QuantitySpecOf<decltype(auto(Q::quantity_spec)), QS>; + +template<Unit UFrom, Unit UTo> +consteval bool integral-conversion-factor(UFrom from, UTo to) // exposition only +{ + return is-integral(get-canonical-unit(from).mag / get-canonical-unit(to).mag); +} + +template<typename T> +concept IsFloatingPoint = treat_as_floating_point<T>; // exposition only + +template<typename FromRep, typename ToRep, auto FromUnit = one, auto ToUnit = one> +concept ValuePreservingTo = // exposition only + Representation<std::remove_cvref_t<FromRep>> && Representation<ToRep> && + Unit<decltype(FromUnit)> && Unit<decltype(ToUnit)> && std::assignable_from<ToRep&, FromRep> && + (IsFloatingPoint<ToRep> || (!IsFloatingPoint<std::remove_cvref_t<FromRep>> && + (integral-conversion-factor(FromUnit, ToUnit)))); + +template<typename QFrom, typename QTo> +concept QuantityConvertibleTo = // exposition only + Quantity<QFrom> && Quantity<QTo> && + QuantitySpecConvertibleTo<QFrom::quantity_spec, QTo::quantity_spec> && + UnitConvertibleTo<QFrom::unit, QTo::unit> && + ValuePreservingTo<typename QFrom::rep, typename QTo::rep, QFrom::unit, QTo::unit> && + requires(QFrom q) { sudo-cast<QTo>(q); }; // see [qty.non.mem.conv] + +template<auto QS, typename Func, typename T, typename U> +concept InvokeResultOf = // exposition only + QuantitySpec<decltype(QS)> && std::regular_invocable<Func, T, U> && + RepresentationOf<std::invoke_result_t<Func, T, U>, QS>; + +template<typename Func, typename Q1, typename Q2, + auto QS = std::invoke_result_t<Func, decltype(auto(Q1::quantity_spec)), + decltype(auto(Q2::quantity_spec))>{}> +concept InvocableQuantities = // exposition only + QuantitySpec<decltype(QS)> && Quantity<Q1> && Quantity<Q2> && + InvokeResultOf<QS, Func, typename Q1::rep, typename Q2::rep>; + +template<auto R1, auto R2> +concept HaveCommonReference = requires { get_common_reference(R1, R2); }; // exposition only + +template<typename Func, Quantity Q1, Quantity Q2> +using common-quantity-for = // exposition only + quantity<get_common_reference(Q1::reference, Q2::reference), + std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>; + +template<typename Func, typename Q1, typename Q2> +concept CommonlyInvocableQuantities = // exposition only + Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> && + std::convertible_to<Q1, common-quantity-for<Func, Q1, Q2>> && + std::convertible_to<Q2, common-quantity-for<Func, Q1, Q2>> && + InvocableQuantities<Func, Q1, Q2, + get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>; + +template<auto R1, auto R2, typename Rep1, typename Rep2> +concept SameValueAs = // exposition only + (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>; + +template<typename T> +using quantity-like-type = // exposition only + quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; + +template<typename T, typename U, typename TT = std::remove_reference_t<T>> +concept Mutable = (!std::is_const_v<TT>) && std::derived_from<TT, U>; // exposition only + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity { +public: + Rep numerical-value; // exposition only + + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + using rep = Rep; + + // [qty.static], static member functions + static constexpr quantity zero() noexcept + requires see below; + static constexpr quantity one() noexcept + requires see below; + static constexpr quantity min() noexcept + requires see below; + static constexpr quantity max() noexcept + requires see below; + + // [qty.cons], constructors and assignment + + quantity() = default; + quantity(const quantity&) = default; + quantity(quantity&&) = default; + ~quantity() = default; + + template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> + constexpr quantity(FwdValue&& v, R2); + + template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> + constexpr quantity(FwdValue&& v, R2); + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity(FwdValue&& v); + + template<QuantityConvertibleTo<quantity> Q> + constexpr explicit(see below) quantity(const Q& q); + + template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> + constexpr explicit(see below) quantity(const Q& q); + + quantity& operator=(const quantity&) = default; + quantity& operator=(quantity&&) = default; + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity& operator=(FwdValue&& v); + + // [qty.conv], conversions + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> + constexpr QuantityOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + // [qty.obs], numerical value observers + + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr rep& numerical_value_ref_in(U) & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr const rep& numerical_value_ref_in(U) const & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + void numerical_value_ref_in(U) const && = delete; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> + constexpr rep numerical_value_in(U) const noexcept; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } + constexpr rep force_numerical_value_in(U) const noexcept; + + // [qty.conv.ops], conversion operations + + template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) + explicit operator V_() const & noexcept; + + template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> + constexpr explicit(see below) operator Q_() const noexcept(see below); + + // [qty.unary.ops], unary operations + + constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; + constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; + + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator++(Q&& q) + requires see below; + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator--(Q&& q) + requires see below; + + constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; + constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; + + // [qty.assign.ops], compound assignment operations + + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); + + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); + + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); + + // [qty.arith.ops], arithmetic operations + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); + + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> + friend constexpr Quantity auto operator/(const Value&, const Q&); + + // [qty.cmp], comparison + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr bool operator==(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); + + // [qty.val.cmp], value comparison + friend constexpr bool is_eq_zero(const quantity& q) requires see below; + friend constexpr bool is_neq_zero(const quantity& q) requires see below; + friend constexpr bool is_lt_zero(const quantity& q) requires see below; + friend constexpr bool is_gt_zero(const quantity& q) requires see below; + friend constexpr bool is_lteq_zero(const quantity& q) requires see below; + friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +}; + +template<Representation Value, Reference R> +quantity(Value, R) -> quantity<R{}, Value>; + +template<Representation Value> +quantity(Value) -> quantity<one, Value>; + +template<QuantityLike Q> +explicit(quantity_like_traits<Q>::explicit_import) quantity(Q) + -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>; + +} +
    quantity<R, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.

    5.6.4 Static member functions [qty.static]

    static constexpr quantity zero() noexcept + requires see below; +static constexpr quantity one() noexcept + requires see below; +static constexpr quantity min() noexcept + requires see below; +static constexpr quantity max() noexcept + requires see below; +
    Let F be one of zero, one, min, and max.
    Returns: {representation_values<rep>​::​F(), R}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { representation_values<rep>::F(); } +

    5.6.5 Constructors and assignment [qty.cons]

    template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> +constexpr quantity(FwdValue&& v, R2); + +template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity(FwdValue&& v); +
    Effects: Initializes numerical-value with std​::​forward<FwdValue>(v).
    template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> +constexpr quantity(FwdValue&& v, R2); +
    Effects: Equivalent to +quantity(quantity<R2{}, Value>{std​::​forward<FwdValue>(v), R2{}}).
    template<QuantityConvertibleTo<quantity> Q> +constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q); +
    Effects: Equivalent to sudo-cast<quantity>(q) ([qty.non.mem.conv]).
    template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> +constexpr explicit(see below) quantity(const Q& q); +
    Effects: Equivalent to: +quantity(::mp_units::quantity{quantity_like_traits<Q>::to_numerical_value(q), + quantity_like_traits<Q>::reference}) +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_import || + !std::convertible_to<typename quantity_like_traits<Q>::rep, Rep> +
    template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity& operator=(FwdValue&& v); +
    Effects: Equivalent to numerical-value = std​::​forward<FwdValue>(v).
    Returns: *this.

    5.6.6 Conversions [qty.conv]

    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), Rep>{*this};
    template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> +constexpr QuantityOf<quantity_spec> auto in() const; +
    Effects: Equivalent to: +return quantity<reference, ToRep>{*this};
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), ToRep>{*this}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}>(*this);
    template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in() const; +
    Effects: Equivalent to: +return value_cast<ToRep>(*this);
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}, ToRep>(*this);

    5.6.7 Numerical value observers [qty.obs]

    template<Unit U> + requires(equivalent(U{}, unit)) +constexpr rep& numerical_value_ref_in(U) & noexcept; +template<Unit U> + requires(equivalent(U{}, unit)) +constexpr const rep& numerical_value_ref_in(U) const & noexcept; +
    Returns: numerical-value.
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> +constexpr rep numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).in(U{}).numerical-value;
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } +constexpr rep force_numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).force_in(U{}).numerical-value;

    5.6.8 Conversion operations [qty.conv.ops]

    template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) +explicit operator V_() const & noexcept; +
    Returns: numerical-value.
    template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> +constexpr explicit(see below) operator Q_() const noexcept(see below); +
    Effects: Equivalent to: +return quantity_like_traits<Q>::from_numerical_value( + numerical_value_in(get_unit(quantity_like_traits<Q>::reference))); +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_export || + !std::convertible_to<Rep, typename quantity_like_traits<Q>::rep> +
    +The exception specification is equivalent to: +noexcept(quantity_like_traits<Q>::from_numerical_value(numerical-value)) && + std::is_nothrow_copy_constructible_v<rep> +

    5.6.9 Unary operations [qty.unary.ops]

    In the following descriptions, +let @ be the operator.
    constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; +constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{@numerical-value, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(const rep v) { + { @v } -> std::common_with<rep>; +} +
    template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator++(Q&& q) + requires see below; +template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator--(Q&& q) + requires see below; +
    Effects: Equivalent to +@q.numerical-value.
    Returns: std​::​forward<Q>(q).
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { @v } -> std::same_as<rep&>; +} +
    constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; +constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{numerical-value@, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { v@ } -> std::common_with<rep>; +} +

    5.6.10 Compound assignment operations [qty.assign.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is %=, then is_neq_zero(rhs) is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.in(lhs.unit).numerical-value.
    Returns: std​::​forward<Q>(lhs).
    Remarks: Let C be +
    • (!treat_as_floating_point<rep>) if @ is %=, and
    • true otherwise.
    +The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && C && +requires(rep& a, const Rep2 b) { + { a @ b } -> std::same_as<rep&>; +} +
    Recommended practice: If equivalent(unit, get_unit(rhs.reference)) is true, +then the expression rhs.in(lhs.unit) is replaced with rhs.
    template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); +template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); +
    Preconditions: If @ is /=, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.
    Returns: std​::​forward<Q>(lhs).
    Remarks: The expression in the requires-clause is equivalent to: +(!Quantity<Value>) && requires(rep& a, const Value b) { + { a @ b } -> std::same_as<rep&>; +} +
    template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); +template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); +
    Effects: Equivalent to: +return std​::​forward<Q>(lhs) @ rhs.numerical-value;
    Remarks: The expression in the requires-clause is equivalent to: +(Q2::unit == ::mp_units::one) && ValuePreservingTo<typename Q2::rep, Rep> && +requires(rep& a, const Q2::rep b) { + { a @ b } -> std::same_as<rep&>; +} +

    5.6.11 Arithmetic operations [qty.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let F be the first argument to CommonlyInvocableQuantities.
    Preconditions: If @ is %, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +using ret = common-quantity-for<F, quantity, quantity<R2, Rep2>>; +const ret ret_lhs(lhs); +const ret ret_rhs(rhs); +return ::mp_units::quantity{ + ret_lhs.numerical_value_ref_in(ret::unit) @ ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; +
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); +
    Effects: Equivalent to: +return lhs @ ​::​mp_units​::​quantity{rhs};
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{lhs} @ rhs;
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{ + lhs.numerical_value_ref_in(unit) @ rhs.numerical_value_ref_in(rhs.unit), R @ R2}; +
    template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); +
    Preconditions: If @ is /, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs.numerical_value_ref_in(unit) @ rhs, R}; +
    template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); +template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> +friend constexpr Quantity auto operator/(const Value& lhs, const Q& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs @ rhs.numerical_value_ref_in(unit), ::mp_units::one @ R}; +

    5.6.12 Comparison [qty.cmp]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let C be +std​::​equality_comparable if @ is ==, and +std​::​three_way_comparable if @ is <=>.
    Effects: Equivalent to: +using ct = std::common_type_t<quantity, quantity<R2, Rep2>>; +const ct ct_lhs(lhs); +const ct ct_rhs(rhs); +return ct_lhs.numerical_value_ref_in(ct::unit) @ ct_rhs.numerical_value_ref_in(ct::unit); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + typename std::common_type_t<quantity, quantity<R2, Rep2>>; +} && C<typename std::common_type_t<quantity, quantity<R2, Rep2>>::rep> +
    template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr bool operator==(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); +
    Let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Returns: lhs.numerical_value_ref_in(unit) @ rhs.
    Remarks: The expression in the requires-clause is equivalent to: +(Q::unit == ::mp_units::one) && C<Rep, Value> +

    5.6.13 Value comparison [qty.val.cmp]

    friend constexpr bool is_eq_zero(const quantity& q) requires see below; +friend constexpr bool is_neq_zero(const quantity& q) requires see below; +friend constexpr bool is_lt_zero(const quantity& q) requires see below; +friend constexpr bool is_gt_zero(const quantity& q) requires see below; +friend constexpr bool is_lteq_zero(const quantity& q) requires see below; +friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +
    Let is_F_zero be the function name.
    Returns:
    Remarks: Let C be +std​::​equality_comparable_with if F is eq or neq, and +std​::​three_way_comparable_with otherwise.
    The expression in the requires-clause is equivalent to: +requires { + { T::zero() } -> C<quantity>; +} +

    5.6.14 Construction helper delta [qty.delta]

    namespace mp_units { + +template<Reference R> +struct delta_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), R{}};

    5.6.15 Non-member conversions [qty.non.mem.conv]

    template<Quantity To, typename FwdFrom, Quantity From = std::remove_cvref_t<FwdFrom>> + requires see below +constexpr To sudo-cast(FwdFrom&& q); // exposition only +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToU)) +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), typename Q::rep>>( + std::forward<FwdQ>(q)); +
    template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires RepresentationOf<ToRep, Q::quantity_spec> && + std::constructible_from<ToRep, typename Q::rep> +constexpr quantity<Q::reference, ToRep> value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<Q::reference, ToRep>>(std::forward<FwdQ>(q)); +
    template<Unit auto ToU, Representation ToRep, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +template<Representation ToRep, Unit auto ToU, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), ToRep>>( + std::forward<FwdQ>(q)); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec> && +std::constructible_from<ToRep, typename Q::rep> +
    template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToQ::unit)) && (ToQ::quantity_spec == Q::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename Q::rep> +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: return sudo-cast<ToQ>(std​::​forward<FwdQ>(q));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    [Example 1: auto length = isq::length(42 * m); +auto distance = quantity_cast<isq::distance>(length); + — end example]
    template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecCastableTo<Q::quantity_spec, ToQS> +constexpr Quantity auto quantity_cast(FwdQ&& q); +
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, make-reference(ToQS, Q::unit)}; +

    5.6.16 std​::​common_type specializations [qty.common.type]

    template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires requires { + { mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference; + typename std::common_type_t<typename Q1::rep, typename Q2::rep>; + requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>, + mp_units::get_common_quantity_spec(Q1::quantity_spec, + Q2::quantity_spec)>; + } +struct std::common_type<Q1, Q2> { + using type = mp_units::quantity<mp_units::get_common_reference(Q1::reference, Q2::reference), + std::common_type_t<typename Q1::rep, typename Q2::rep>>; +}; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires(Q::unit == mp_units::one) && requires { + typename mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; + } +struct std::common_type<Q, Value> { + using type = mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; +}; +

    5.7 Quantity point [qty.pt]

    5.7.1 General [qty.pt.general]

    Subclause [qty.pt] describes the class template quantity_point +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of an affine space (IEC 60050, 102-03-02,102-04-01).

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.1 General [qty.pt.orig.general]

    This subclause specifies the components +for defining the origin of an affine space.
    An origin is a point from which measurements (IEC 60050, 112-04-01) take place.

    5.7.2.2 Concepts [qty.pt.orig.concepts]

    template<typename T> +concept PointOrigin = SymbolicConstant<T> && std::derived_from<T, point-origin-interface>; + +template<typename T, auto QS> +concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<decltype(QS), T::quantity-spec>; + +template<typename T, auto V> +concept SameAbsolutePointOriginAs = // exposition only + PointOrigin<T> && PointOrigin<decltype(V)> && same-absolute-point-origins(T{}, V); +

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.1 Absolute [qty.abs.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct absolute_point_origin : point-origin-interface { + static constexpr QuantitySpec auto quantity-spec = QS; // exposition only +}; + +} +
    An absolute origin is an origin +chosen by convention and not defined in terms of another origin.
    A specialization of absolute_point_origin is used as a base type when defining an absolute origin.
    QS is the quantity the origin represents.

    5.7.2.3.2 Relative [qty.rel.pt.orig]

    namespace mp_units { + +template<QuantityPoint auto QP> +struct relative_point_origin : point-origin-interface { + static constexpr QuantityPoint auto quantity-point = QP; // exposition only + static constexpr QuantitySpec auto quantity-spec = see below; // exposition only + static constexpr PointOrigin auto absolute-point-origin = // exposition only + QP.absolute_point_origin; +}; + +} +
    A relative origin is an origin +of a subspace (IEC 60050, 102-03-03).
    A specialization of relative_point_origin is used as a base type when defining a relative origin O.
    O is offset from QP.absolute_point_origin by QP.quantity_from_zero().
    The member quantity-spec is equal to +QP.point_origin.quantity-spec if +QuantityKindSpec<decltype(auto(QP.quantity-spec))> + +is satisfied, and +to QP.quantity-spec otherwise.

    5.7.2.3.3 Zeroth [qty.zeroth.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct zeroth_point_origin_ final : absolute_point_origin<QS> {}; + +} +
    zeroth_point_origin_<QS> represents an origin +chosen by convention as the value 0 of the quantity QS.

    5.7.2.4 Operations [qty.pt.orig.ops]

    namespace mp_units { + +struct point-origin-interface { + template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); + template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); + + template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> + friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; + + template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below + friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); + + template<PointOrigin PO1, PointOrigin PO2> + friend consteval bool operator==(PO1 po1, PO2 po2); +}; + +} +
    template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); +template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); +
    Effects: Equivalent to: +return quantity_point{std​::​forward<FwdQ>(q), PO{}};
    template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> +friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; +
    Effects: Equivalent to: +return po + -q;
    template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below +friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>()) { + return po1 - po2.quantity-point; +} else if constexpr (is-derived-from-specialization-of<PO2, absolute_point_origin>()) { + return po1.quantity-point - po2; +} else { + return po1.quantity-point - po2.quantity-point; +} +
    Remarks: The expression in the requires-clause is equivalent to: +QuantitySpecOf<decltype(auto(PO1::quantity-spec)), PO2::quantity-spec> && + (is-derived-from-specialization-of<PO1, relative_point_origin>() || + is-derived-from-specialization-of<PO2, relative_point_origin>()) +
    template<PointOrigin PO1, PointOrigin PO2> +friend consteval bool operator==(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return std::is_same_v<PO1, PO2> || + (is-specialization-of<PO1, zeroth_point_origin>() && + is-specialization-of<PO2, zeroth_point_origin>() && + interconvertible(po1.quantity-spec, po2.quantity-spec)); +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return PO1::quantity-point == PO2::quantity-point; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO1::quantity-point.quantity_from_zero()); +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO2::quantity-point.quantity_from_zero()); +

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.1 Same absolute [qty.same.abs.pt.origs]

    template<PointOrigin PO1, PointOrigin PO2> +consteval bool same-absolute-point-origins(PO1 po1, PO2 po2); // exposition only +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return po1 == po2; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1.absolute-point-origin == po2.absolute-point-origin; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return po1.absolute-point-origin == po2; +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1 == po2.absolute-point-origin; +else + return false; +

    5.7.2.5.2 Default [qty.def.pt.orig]

    template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); +
    Effects: Equivalent to: +if constexpr (requires { get_unit(R{}).point-origin; }) + return get_unit(R{}).point-origin; +else + return zeroth_point_origin<get_quantity_spec(R{})>; +

    5.7.3 Interoperability [qty.pt.like]

    template<typename T> +concept QuantityPointLike = + !QuantityPoint<T> && + qty-like-impl<T, quantity_point_like_traits> && // see [qty.like] + requires { + typename quantity_point<quantity_point_like_traits<T>::reference, + quantity_point_like_traits<T>::point_origin, + typename quantity_point_like_traits<T>::rep>; + }; +

    5.7.4 Class template quantity_point [qty.pt.syn]

    namespace mp_units { + +template<typename T> +concept QuantityPoint = (is-derived-from-specialization-of<T, quantity_point>()); + +template<typename QP, auto V> +concept QuantityPointOf = + QuantityPoint<QP> && (QuantitySpecOf<decltype(auto(QP::quantity_spec)), V> || + SameAbsolutePointOriginAs<decltype(auto(QP::absolute_point_origin)), V>); + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point { +public: + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + static constexpr PointOrigin auto absolute_point_origin = see below; + static constexpr PointOrigin auto point_origin = PO; + using rep = Rep; + using quantity_type = quantity<reference, Rep>; + + quantity_type quantity-from-origin; // exposition only + + // [qty.pt.static], static member functions + static constexpr quantity_point min() noexcept + requires see below; + static constexpr quantity_point max() noexcept + requires see below; + + // [qty.pt.cons], constructors and assignment + + quantity_point() = default; + quantity_point(const quantity_point&) = default; + quantity_point(quantity_point&&) = default; + ~quantity_point() = default; + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) + constexpr explicit quantity_point(FwdQ&& q); + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> + constexpr quantity_point(FwdQ&& q, decltype(PO)); + + template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> + constexpr quantity_point(FwdQ&& q, PO2); + + template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> + constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); + + template<QuantityPointLike QP> + requires see below + constexpr explicit(see below) quantity_point(const QP& qp); + + quantity_point& operator=(const quantity_point&) = default; + quantity_point& operator=(quantity_point&&) = default; + + // [qty.pt.conv], conversions + + template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> + constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + // [qty.pt.obs], quantity value observers + + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr quantity_type& quantity_ref_from(PO2) & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + void quantity_ref_from(PO2) const && = delete; + + template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } + constexpr Quantity auto quantity_from(PO2) const; + + template<QuantityPointOf<absolute_point_origin> QP> + constexpr Quantity auto quantity_from(const QP&) const; + + constexpr Quantity auto quantity_from_zero() const; + + // [qty.pt.conv.ops], conversion operations + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() const & noexcept(see below); + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() && noexcept(see below); + + // [qty.pt.unary.ops], unary operations + + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; + + constexpr quantity_point operator++(int) + requires see below; + constexpr quantity_point operator--(int) + requires see below; + + // [qty.pt.assign.ops], compound assignment operations + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); + + // [qty.pt.arith.ops], arithmetic operations + + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; + + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(const QP& qp, PO2 po); + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(PO2 po, const QP& qp); + + // [qty.pt.cmp], comparison + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr bool operator==(const QP& lhs, const QP2& rhs); + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +}; + +template<Quantity Q> +explicit quantity_point(Q q) + -> quantity_point<Q::reference, default_point_origin(Q::reference), typename Q::rep>; + +template<Quantity Q, PointOriginFor<Q::quantity_spec> PO> +quantity_point(Q, PO) -> quantity_point<Q::reference, PO{}, typename Q::rep>; + +template<QuantityPointLike QP, typename Traits = quantity_point_like_traits<QP>> +explicit(quantity_point_like_traits<QP>::explicit_import) quantity_point(QP) + -> quantity_point<Traits::reference, Traits::point_origin, typename Traits::rep>; + +} +
    quantity_point<R, PO, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.
    The member absolute_point_origin is equal to PO if +is-derived-from-specialization-of<decltype(PO), absolute_point_origin>() + +is true, and +to PO.quantity-point.absolute_point_origin otherwise.

    5.7.5 Static member functions [qty.pt.static]

    static constexpr quantity_point min() noexcept + requires see below; +static constexpr quantity_point max() noexcept + requires see below; +
    Let F be one of min and max.
    Returns: {quantity_type​::​F(), PO}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity_type::F(); } +

    5.7.6 Constructors [qty.pt.cons]

    template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) +constexpr explicit quantity_point(FwdQ&& q); + +template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> +constexpr quantity_point(FwdQ&& q, decltype(PO)); +
    Effects: Initializes quantity-from-origin with std​::​forward<FwdQ>(q).
    template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> +constexpr quantity_point(FwdQ&& q, PO2); +
    Effects: Equivalent to: +quantity_point(quantity_point<Q::reference, PO2{}, typename Q::rep>{std::forward<FwdQ>(q), + PO2{}}) +
    template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> +constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); +
    Effects: If point_origin == QP​::​point_origin is true, +initializes quantity-from-origin with qp.quantity_ref_from(point_origin).
    Otherwise, initializes quantity-from-origin with qp - point_origin.
    template<QuantityPointLike QP> + requires see below +constexpr explicit(see below) quantity_point(const QP& qp); +
    Let Traits be quantity_point_like_traits<QP>.
    Effects: Initializes quantity-from-origin with +Traits::to_numerical_value(qp), get_unit(Traits::reference) +
    Remarks: The expression in the requires-clause is equivalent to: +(Traits::point_origin == point_origin) && + std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +
    +The expression inside explicit is equivalent to: +Traits::explicit_import || + !std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +

    5.7.7 Conversions [qty.pt.conv]

    template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> +constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; +
    Effects: Equivalent to: +if constexpr (std::is_same_v<NewPO, decltype(point_origin)>) + return *this; +else + return ::mp_units::quantity_point{*this - new_origin, new_origin}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; +
    Let converted-quantity-expr be an expression denoting +the function call to the corresponding member of quantity_ref_from(point_origin).
    Effects: Equivalent to: +return ::mp_units::quantity_point{converted-quantity-expr, point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { converted-quantity-expr; } +

    5.7.8 Quantity value observers [qty.pt.obs]

    template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr quantity_type& quantity_ref_from(PO2) & noexcept; +template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; +
    Returns: quantity-from-origin.
    template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } +constexpr Quantity auto quantity_from(PO2 rhs) const; + +template<QuantityPointOf<absolute_point_origin> QP> +constexpr Quantity auto quantity_from(const QP& rhs) const; +
    Effects: Equivalent to: +return *this - rhs;
    constexpr Quantity auto quantity_from_zero() const; +
    Effects: Equivalent to: +if constexpr (requires { unit.point-origin; }) { + // can lose the input unit + const auto q = quantity_from(unit.point-origin); + if constexpr (requires { q.in(unit); }) + // restore the unit + return q.in(unit); + else + return q; +} else + return quantity_from(absolute_point_origin); +

    5.7.9 Conversion operations [qty.pt.conv.ops]

    template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() const & noexcept(see below); +template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() && noexcept(see below); +
    Let Traits be quantity_point_like_traits<QP>.
    Let result-expr be +Traits::from_numerical_value(std::move(quantity-from-origin).numerical-value) +
    Returns: result-expr.
    Remarks: The expression in the requires-clause is equivalent to: +(point_origin == Traits::point_origin) && + std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +The expression inside explicit is equivalent to: +Traits::explicit_export || + !std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +Let T be +std​::​is_nothrow_copy_constructible_v for the first signature, and +std​::​is_nothrow_move_constructible_v for the second signature.
    The exception specification is equivalent to: +noexcept(result-expr) && T<rep> +

    5.7.10 Unary operations [qty.pt.unary.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; +template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; +
    Effects: Equivalent to +@qp.quantity-from-origin.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +requires { @qp.quantity-from-origin; } +
    constexpr quantity_point operator++(int) + requires see below; +constexpr quantity_point operator--(int) + requires see below; +
    Effects: Equivalent to: +return {quantity-from-origin@, PO};
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity-from-origin@; } +

    5.7.11 Compound assignment operations [qty.pt.assign.ops]

    template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); +template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); +
    Let @ be the operator.
    Effects: Equivalent to +qp.quantity-from-origin @ q.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity_type> && + requires { qp.quantity-from-origin @ q; } +

    5.7.12 Arithmetic operations [qty.pt.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +
    Effects: Equivalent to: +if constexpr (is-specialization-of<PO, zeroth_point_origin>()) + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q}; +else + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q, PO}; +
    Remarks: The expression in the requires-clause is equivalent to: +ReferenceOf<decltype(R2), PO.quantity-spec> && requires { + qp.quantity_ref_from(PO) @ q; +} +
    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> +friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; +
    Effects: Equivalent to: +return lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin) + + (lhs.point_origin - rhs.point_origin); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin); } +
    Recommended practice: The subtraction of two equal origins is not evaluated.
    template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(const QP& qp, PO2 po); +template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(PO2 po, const QP& qp); +
    Effects: For the first signature, +equivalent to: +if constexpr (point_origin == po) + return qp.quantity_ref_from(point_origin); +else if constexpr (is-derived-from-specialization-of<PO2, + ::mp_units::absolute_point_origin>()) { + return qp.quantity_ref_from(point_origin) + (qp.point_origin - qp.absolute_point_origin); +} else { + return qp.quantity_ref_from(point_origin) - + po.quantity-point.quantity_ref_from(po.quantity-point.point_origin) + + (qp.point_origin - po.quantity-point.point_origin); +} +
    +For the second signature, +equivalent to: return -(qp - po);
    Remarks: The expression in the requires-clause is equivalent to: +QuantityPointOf<quantity_point, PO2{}> && + ReferenceOf<decltype(auto(reference)), PO2::quantity-spec> +
    Recommended practice: The subtraction of two equal origins is not evaluated.

    5.7.13 Comparison [qty.pt.cmp]

    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr bool operator==(const QP& lhs, const QP2& rhs); +template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +
    Let @ be the operator, and +let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Effects: Equivalent to: +return lhs - lhs.absolute_point_origin @ rhs - rhs.absolute_point_origin; +
    Remarks: The expression in the requires-clause is equivalent to: +C<quantity_type, typename QP2::quantity_type> +
    Recommended practice: If the origins are equal, instead evaluate +lhs.quantity_ref_from(point_origin) @ rhs.quantity_ref_from(QP2::point_origin) +

    5.7.14 Construction helper point [qty.point]

    namespace mp_units { + +template<Reference R> +struct point_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity_point{quantity{std​::​forward<FwdRep>(lhs), R{}}};

    5.7.15 Non-member conversions [qty.pt.non.mem.conv]

    template<QuantityPoint ToQP, typename FwdFromQP, + QuantityPoint FromQP = std::remove_cvref_t<FwdFromQP>> + requires see below +constexpr QuantityPoint auto sudo-cast(FwdFromQP&& qp); +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToU)) +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires RepresentationOf<ToRep, QP::quantity_spec> && + std::constructible_from<ToRep, typename QP::rep> +constexpr quantity_point<QP::reference, QP::point_origin, ToRep> value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return {value_cast<ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), QP::point_origin}; +
    template<Unit auto ToU, Representation ToRep, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +template<Representation ToRep, Unit auto ToU, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU, ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec> && +std::constructible_from<ToRep, typename QP::rep> +
    template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQ::unit)) && (ToQ::quantity_spec == QP::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToQ>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQP::unit)) && + (ToQP::quantity_spec == QP::quantity_spec) && + (same-absolute-point-origins(ToQP::point_origin, QP::point_origin)) && + std::constructible_from<typename ToQP::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return sudo-cast<ToQP>(std​::​forward<FwdQP>(qp));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires QuantitySpecCastableTo<QP::quantity_spec, ToQS> +constexpr QuantityPoint auto quantity_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin), + QP::point_origin}; +

    5.9 std​::​chrono interoperability [qty.chrono]

    namespace mp_units { + +template<typename Period> +consteval auto time-unit-from-chrono-period() +{ + using namespace si; + + if constexpr (is_same_v<Period, std::chrono::nanoseconds::period>) + return nano<second>; + else if constexpr (is_same_v<Period, std::chrono::microseconds::period>) + return micro<second>; + else if constexpr (is_same_v<Period, std::chrono::milliseconds::period>) + return milli<second>; + else if constexpr (is_same_v<Period, std::chrono::seconds::period>) + return second; + else if constexpr (is_same_v<Period, std::chrono::minutes::period>) + return minute; + else if constexpr (is_same_v<Period, std::chrono::hours::period>) + return hour; + else if constexpr (is_same_v<Period, std::chrono::days::period>) + return day; + else if constexpr (is_same_v<Period, std::chrono::weeks::period>) + return mag<7> * day; + else + return mag_ratio<Period::num, Period::den> * second; +} + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>> { + static constexpr auto reference = time-unit-from-chrono-period<Period>(); + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = false; + using rep = Rep; + using T = std::chrono::duration<Rep, Period>; + + static constexpr rep to_numerical_value(const T& q) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return q.count(); + } + + static constexpr T from_numerical_value(const rep& v) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return T(v); + } +}; + +template<typename Clock> +struct chrono_point_origin_ final : absolute_point_origin<isq::time> { + using clock = Clock; +}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>> { + static constexpr auto reference = time-unit-from-chrono-period<Period>(); + static constexpr auto point_origin = chrono_point_origin<Clock>; + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = false; + using rep = Rep; + using T = std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>; + + static constexpr rep to_numerical_value(const T& tp) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return tp.time_since_epoch().count(); + } + + static constexpr T from_numerical_value(const rep& v) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return T(std::chrono::duration<Rep, Period>(v)); + } +}; + +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/fulltoc.html b/HEAD/api_reference/gen/fulltoc.html index b9e9f504..19bae7f8 100644 --- a/HEAD/api_reference/gen/fulltoc.html +++ b/HEAD/api_reference/gen/fulltoc.html @@ -11,4 +11,4 @@ h4 { margin: 0.1em 5pt 0.1em 5pt; border-bottom: 1px dashed rgba(0, 0, 0, 0.2); h3 { border-bottom-color: #b0b0b05a; } h4 { border-bottom-color: #b0b0b05a; } } -

    mp-units Library Reference Documentations

    (Generated on 2024-12-01 from the LaTeX sources by cxxdraft-htmlgen. This is not an ISO publication.)

    Note: this is an early draft. It's known to be incomplet and incorrekt, and it has lots of bad formatting.

    Contents

    1 Scope [scope]

    2 References [refs]

    3 Terms and definitions [defs]

    4 Specification [spec]

    4.1 External [spec.ext]

    4.2 Categories [spec.cats]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    5 Quantities library [qties]

    5.2 Module mp_units synopsis [mp.units.syn]

    5.3 Module mp_units.core synopsis [mp.units.core.syn]

    5.4 Module mp_units.systems synopsis [mp.units.systems.syn]

    5.8 Types [qty.types]

    5.8.2 Class template quantity [qty.type]

    5.8.3 Class template quantity_point [qty.point.type]

    5.9 Compatibility [qty.compat]

    5.10 Dimension one [qty.one]

    5.12 std​::​chrono compatibility [qty.chrono]

    Index

    Index of library modules

    Index of library names

    Index of library concepts

    \ No newline at end of file +

    mp-units Library Reference Documentations

    (Generated on 2024-12-08 from the LaTeX sources by cxxdraft-htmlgen. This is not an ISO publication.)

    Note: this is an early draft. It's known to be incomplet and incorrekt, and it has lots of bad formatting.

    Contents

    1 Scope [scope]

    2 References [refs]

    3 Terms and definitions [defs]

    4 Specification [spec]

    4.1 External [spec.ext]

    4.2 Categories [spec.cats]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    5 Quantities and units library [quantities]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.1 Module mp_units synopsis [mp.units.syn]

    5.2.2 Module mp_units.core synopsis [mp.units.core.syn]

    5.2.3 Module mp_units.systems synopsis [mp.units.systems.syn]

    5.4 Reference [qty.ref]

    5.4.6 Class template reference [qty.ref.syn]

    5.4.7 Operations [qty.ref.ops]

    5.4.8 Comparison [qty.ref.cmp]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    5.6 Quantity [qty]

    5.6.2 Interoperability [qty.like]

    5.6.3 Class template quantity [qty.syn]

    5.6.4 Static member functions [qty.static]

    5.6.5 Constructors and assignment [qty.cons]

    5.6.6 Conversions [qty.conv]

    5.6.7 Numerical value observers [qty.obs]

    5.6.8 Conversion operations [qty.conv.ops]

    5.6.9 Unary operations [qty.unary.ops]

    5.6.10 Compound assignment operations [qty.assign.ops]

    5.6.11 Arithmetic operations [qty.arith.ops]

    5.6.12 Comparison [qty.cmp]

    5.6.13 Value comparison [qty.val.cmp]

    5.6.14 Construction helper delta [qty.delta]

    5.6.15 Non-member conversions [qty.non.mem.conv]

    5.6.16 std​::​common_type specializations [qty.common.type]

    5.7 Quantity point [qty.pt]

    5.7.3 Interoperability [qty.pt.like]

    5.7.4 Class template quantity_point [qty.pt.syn]

    5.7.5 Static member functions [qty.pt.static]

    5.7.6 Constructors [qty.pt.cons]

    5.7.7 Conversions [qty.pt.conv]

    5.7.8 Quantity value observers [qty.pt.obs]

    5.7.9 Conversion operations [qty.pt.conv.ops]

    5.7.10 Unary operations [qty.pt.unary.ops]

    5.7.11 Compound assignment operations [qty.pt.assign.ops]

    5.7.12 Arithmetic operations [qty.pt.arith.ops]

    5.7.13 Comparison [qty.pt.cmp]

    5.7.14 Construction helper point [qty.point]

    5.7.15 Non-member conversions [qty.pt.non.mem.conv]

    5.9 std​::​chrono interoperability [qty.chrono]

    Index

    Index of library modules

    Index of library names

    Index of library concepts

    Index of implementation-defined behavior

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/generalindex.html b/HEAD/api_reference/gen/generalindex.html index 2eac41ef..1eea99a3 100644 --- a/HEAD/api_reference/gen/generalindex.html +++ b/HEAD/api_reference/gen/generalindex.html @@ -1 +1 @@ -14882: Index

    Index


    D M

    Q R S T


    D

    definitions, [defs]

    M

    module
    mp-units, [spec.mods]
    mp-units library, [scope]

    Q

    quantity point type, see type, quantity point
    quantity type, see type, quantity

    R

    references, [refs]

    S

    scope, [scope]

    T

    type
    quantity point, [qty.point.type]
    \ No newline at end of file +14882: Index

    Index


    A D

    M N O Q R S U


    A

    absolute origin, see origin, absolute

    D

    definitions, [defs]

    M

    module
    mp-units, [spec.mods]
    mp-units library, [scope]

    N

    named quantity, see quantity, named
    named unit, see unit, named

    O

    Q

    quantity

    R

    references, [refs]
    relative origin, see origin, relative

    S

    scope, [scope]

    U

    unit
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/get.common.qty.spec.html b/HEAD/api_reference/gen/get.common.qty.spec.html new file mode 100644 index 00000000..6b8ee4b6 --- /dev/null +++ b/HEAD/api_reference/gen/get.common.qty.spec.html @@ -0,0 +1,45 @@ +[get.common.qty.spec]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

    consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; +
    Let +
    • q1 be qs...[0],
    • q2 be qs...[1],
    • Q1 be decltype(q1),
    • Q2 be decltype(q2), and
    • rest be a pack denoting the elements of qs without q1 and q2.
    Effects: Equivalent to: +if constexpr (sizeof...(qs) == 1) + return q1; +else if constexpr (sizeof...(qs) == 2) { + using QQ1 = decltype(remove-kind(q1)); + using QQ2 = decltype(remove-kind(q2)); + + if constexpr (std::is_same_v<Q1, Q2>) + return q1; + else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) + return QQ1{}; + else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) + return QQ2{}; + else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || + (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && + implicitly_convertible(Q1{}, Q2{}))) + return q2; + else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || + (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && + implicitly_convertible(Q2{}, Q1{}))) + return q1; + else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) + return *common_base; + else if constexpr (implicitly_convertible(Q1{}, Q2{})) + return q2; + else if constexpr (implicitly_convertible(Q2{}, Q1{})) + return q1; + else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), + get-kind-tree-root(Q2{}))) + return get-kind-tree-root(q2); + else + return get-kind-tree-root(q1); +} else + return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(qs) != 0 && + (sizeof...(qs) == 1 || + (sizeof...(qs) == 2 && + (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || + QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || + requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); })) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/impldefindex.html b/HEAD/api_reference/gen/impldefindex.html new file mode 100644 index 00000000..19032070 --- /dev/null +++ b/HEAD/api_reference/gen/impldefindex.html @@ -0,0 +1 @@ +14882: Index of implementation-defined behavior

    Index of implementation-defined behavior

    behavior of unit-magnitude operations that do not fit in a std​::​intmax_t, [qty.unit.mag.types]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/index.html b/HEAD/api_reference/gen/index.html index eac15a2b..ce61df26 100644 --- a/HEAD/api_reference/gen/index.html +++ b/HEAD/api_reference/gen/index.html @@ -12,4 +12,4 @@ div.tocChapter { display: none; } h3 { border-bottom-color: #b0b0b05a; } h4 { border-bottom-color: #b0b0b05a; } } -

    mp-units Library Reference Documentations

    (Generated on 2024-12-01 from the LaTeX sources by cxxdraft-htmlgen. This is not an ISO publication.)

    Note: this is an early draft. It's known to be incomplet and incorrekt, and it has lots of bad formatting.

    Contents

    2 References [refs][refs]

    3 Terms and definitions [defs][defs]

    4 Specification [spec][spec]

    4.1 External [spec.ext]

    4.2 Categories [spec.cats]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    5 Quantities library [qties][qties]

    5.2 Module mp_units synopsis [mp.units.syn]

    5.3 Module mp_units.core synopsis [mp.units.core.syn]

    5.4 Module mp_units.systems synopsis [mp.units.systems.syn]

    5.8 Types [qty.types]

    5.8.2 Class template quantity [qty.type]

    5.8.3 Class template quantity_point [qty.point.type]

    5.9 Compatibility [qty.compat]

    5.10 Dimension one [qty.one]

    5.12 std​::​chrono compatibility [qty.chrono]

    Index

    Index of library modules

    Index of library names

    Index of library concepts

    \ No newline at end of file +

    mp-units Library Reference Documentations

    (Generated on 2024-12-08 from the LaTeX sources by cxxdraft-htmlgen. This is not an ISO publication.)

    Note: this is an early draft. It's known to be incomplet and incorrekt, and it has lots of bad formatting.

    Contents

    2 References [refs][refs]

    3 Terms and definitions [defs][defs]

    4 Specification [spec][spec]

    4.1 External [spec.ext]

    4.2 Categories [spec.cats]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    5 Quantities and units library [quantities][quantities]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.1 Module mp_units synopsis [mp.units.syn]

    5.2.2 Module mp_units.core synopsis [mp.units.core.syn]

    5.2.3 Module mp_units.systems synopsis [mp.units.systems.syn]

    5.4 Reference [qty.ref]

    5.4.6 Class template reference [qty.ref.syn]

    5.4.7 Operations [qty.ref.ops]

    5.4.8 Comparison [qty.ref.cmp]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    5.6 Quantity [qty]

    5.6.2 Interoperability [qty.like]

    5.6.3 Class template quantity [qty.syn]

    5.6.4 Static member functions [qty.static]

    5.6.5 Constructors and assignment [qty.cons]

    5.6.6 Conversions [qty.conv]

    5.6.7 Numerical value observers [qty.obs]

    5.6.8 Conversion operations [qty.conv.ops]

    5.6.9 Unary operations [qty.unary.ops]

    5.6.10 Compound assignment operations [qty.assign.ops]

    5.6.11 Arithmetic operations [qty.arith.ops]

    5.6.12 Comparison [qty.cmp]

    5.6.13 Value comparison [qty.val.cmp]

    5.6.14 Construction helper delta [qty.delta]

    5.6.15 Non-member conversions [qty.non.mem.conv]

    5.6.16 std​::​common_type specializations [qty.common.type]

    5.7 Quantity point [qty.pt]

    5.7.3 Interoperability [qty.pt.like]

    5.7.4 Class template quantity_point [qty.pt.syn]

    5.7.5 Static member functions [qty.pt.static]

    5.7.6 Constructors [qty.pt.cons]

    5.7.7 Conversions [qty.pt.conv]

    5.7.8 Quantity value observers [qty.pt.obs]

    5.7.9 Conversion operations [qty.pt.conv.ops]

    5.7.10 Unary operations [qty.pt.unary.ops]

    5.7.11 Compound assignment operations [qty.pt.assign.ops]

    5.7.12 Arithmetic operations [qty.pt.arith.ops]

    5.7.13 Comparison [qty.pt.cmp]

    5.7.14 Construction helper point [qty.point]

    5.7.15 Non-member conversions [qty.pt.non.mem.conv]

    5.9 std​::​chrono interoperability [qty.chrono]

    Index

    Index of library modules

    Index of library names

    Index of library concepts

    Index of implementation-defined behavior

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/kind.of.qty.html b/HEAD/api_reference/gen/kind.of.qty.html new file mode 100644 index 00000000..7bd79ed0 --- /dev/null +++ b/HEAD/api_reference/gen/kind.of.qty.html @@ -0,0 +1,11 @@ +[kind.of.qty]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.4 Kind of [kind.of.qty]

    namespace mp_units { + +template<QuantitySpec Q> + requires(!QuantityKindSpec<Q>) && (get-kind-tree-root(Q{}) == Q{}) +struct kind_of_ final : Q::base-type { + using base-type = kind_of_; // exposition only + static constexpr auto quantity-spec = Q{}; // exposition only +}; + +} +
    kind_of<Q> represents a kind of quantity (IEC 60050, 112-01-04) Q.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/libraryindex.html b/HEAD/api_reference/gen/libraryindex.html index 76f41d15..0276988f 100644 --- a/HEAD/api_reference/gen/libraryindex.html +++ b/HEAD/api_reference/gen/libraryindex.html @@ -1 +1 @@ -14882: Index of library names

    Index of library names


    I R

    S


    I

    is_scalar, [qty.traits]
    is_tensor, [qty.traits]
    is_vector, [qty.traits]

    R

    representation, [qty.concepts]
    representation_of, [qty.concepts]

    S

    some_quantity_spec, [qty.concepts]
    some_reference, [mp.units.core.syn]
    \ No newline at end of file +14882: Index of library names

    Index of library names


    A B

    C D E F G H I K M N O P Q R S T U V Z


    A

    absolute_point_origin, [qty.abs.pt.orig]
    AssociatedUnit
    convertible, [qty.ref.cmp]
    get-associated-quantity, [assoc.qty]
    get_common_reference, [qty.ref.obs]
    get_quantity_spec, [qty.unit.obs]
    get_unit, [qty.unit.obs]
    operator*, [qty.ref.syn]
    operator/, [qty.ref.syn]
    operator==, [qty.ref.cmp]
    AssociatedUnit, [qty.unit.concepts]

    B

    base_dimension, [qty.dim.types]

    C

    canonical-unit, [qty.canon.unit]
    castable
    QuantitySpec, [qty.spec.conv]
    cbrt
    Dimension, [qty.dim.ops]
    QuantitySpec, [qty.spec.ops]
    reference, [qty.ref.syn]
    character_set, [mp.units.core.syn]
    chrono_point_origin, [mp.units.systems.syn]
    chrono_point_origin_, [qty.chrono]
    clone-kind-of
    QuantitySpec, [qty.spec.utils]
    common-magnitude
    UnitMagnitude, [qty.unit.mag.utils]
    common-ratio
    common_unit, [qty.common.unit]
    convertible
    AssociatedUnit, [qty.ref.cmp]
    reference, [qty.ref.cmp]
    cubic

    D

    default_point_origin
    delta_, [qty.delta]
    operator(), [qty.delta]
    derived_dimension, [qty.dim.types]
    derived_quantity_spec, [derived.qty]
    derived_unit, [qty.derived.unit]
    Dimension
    dimension_symbol, [qty.dim.sym.fmt]
    dimension_symbol_to, [qty.dim.sym.fmt]
    inverse, [qty.dim.ops]
    operator*, [qty.dim.ops]
    operator/, [qty.dim.ops]
    operator==, [qty.dim.ops]
    dimension-interface, [qty.dim.ops]
    dimension_symbol
    dimension_symbol_formatting, [mp.units.core.syn]
    dimension_symbol_to
    DimensionOf, [qty.dim.concepts]
    disable_complex, [qty.char.traits]
    disable_scalar, [qty.char.traits]
    std​::​complex, [mp.units.core.syn]
    disable_vector, [qty.char.traits]

    E

    empty
    symbol_text, [qty.sym.txt]
    equivalent
    explicitly_convertible
    QuantitySpec, [qty.spec.conv]
    expr-fractions, [qty.sym.expr.algos]
    expr-multiply, [qty.sym.expr.algos]

    F

    force_in
    quantity, [qty.conv]
    quantity_point, [qty.pt.conv]
    force_numerical_value_in
    quantity, [qty.obs]

    G

    get-associated-quantity
    AssociatedUnit, [assoc.qty]
    get-canonical-unit
    get-common-base
    QuantitySpec, [qty.get.common.base]
    get-kind-tree-root
    QuantitySpec, [qty.get.kind]
    get_common_quantity_spec
    QuantitySpec, [get.common.qty.spec]
    get_common_reference, [qty.ref.obs]
    AssociatedUnit, [qty.ref.obs]
    reference, [qty.ref.obs]
    get_common_unit
    get_kind
    QuantitySpec, [qty.get.kind]
    get_quantity_spec
    AssociatedUnit, [qty.unit.obs]
    reference, [qty.ref.obs]
    get_unit
    AssociatedUnit, [qty.unit.obs]
    reference, [qty.ref.obs]

    H

    has-associated-quantity

    I

    implicitly_convertible
    QuantitySpec, [qty.spec.conv]
    in
    quantity, [qty.conv]
    quantity_point, [qty.pt.conv]
    interconvertible
    QuantitySpec, [qty.spec.conv]
    inverse
    Dimension, [qty.dim.ops]
    QuantitySpec, [qty.spec.ops]
    reference, [qty.ref.syn]
    is-child-of
    QuantitySpec, [qty.is.child.of]
    is-derived-from-specialization-of, [qty.utils.non.types]
    is-integral
    is-positive-integral-power
    UnitMagnitude, [qty.unit.mag.utils]
    is-specialization-of, [qty.utils.non.types]
    is_eq_zero
    quantity, [qty.val.cmp]
    is_gt_zero
    quantity, [qty.val.cmp]
    is_gteq_zero
    quantity, [qty.val.cmp]
    is_lt_zero
    quantity, [qty.val.cmp]
    is_lteq_zero
    quantity, [qty.val.cmp]
    is_neq_zero
    quantity, [qty.val.cmp]

    K

    kind_of_, [kind.of.qty]

    M

    mag_constant, [qty.unit.mag.types]
    make-reference
    QuantitySpec, [qty.spec.utils]
    max
    quantity, [qty.static]
    quantity_point, [qty.pt.static]
    min
    quantity, [qty.static]
    quantity_point, [qty.pt.static]

    N

    named_unit, [qty.named.unit]
    numerical_value_in
    quantity, [qty.obs]
    numerical_value_ref_in
    quantity, [qty.obs]

    O

    operator%
    quantity, [qty.arith.ops]
    operator%=
    operator()
    delta_, [qty.delta]
    point_, [qty.point]
    QuantitySpec, [qty.spec.ops]
    operator*
    AssociatedUnit, [qty.ref.syn]
    Dimension, [qty.dim.ops]
    QuantitySpec, [qty.spec.ops]
    Reference, [qty.ref.ops]
    reference, [qty.ref.syn]
    Representation, [qty.ref.ops]
    operator*=
    operator+
    point-origin-interface, [qty.pt.orig.ops]
    quantity_point, [qty.pt.arith.ops]
    symbol_text, [qty.sym.txt]
    operator++
    quantity, [qty.unary.ops]
    quantity_point, [qty.pt.unary.ops]
    operator+=
    quantity_point, [qty.pt.assign.ops]
    operator-
    point-origin-interface, [qty.pt.orig.ops]
    PointOrigin, [qty.pt.arith.ops]
    quantity_point, [qty.pt.arith.ops]
    operator--
    quantity, [qty.unary.ops]
    quantity_point, [qty.pt.unary.ops]
    operator-=
    quantity_point, [qty.pt.assign.ops]
    operator/
    AssociatedUnit, [qty.ref.syn]
    Dimension, [qty.dim.ops]
    QuantitySpec, [qty.spec.ops]
    Reference, [qty.ref.ops]
    reference, [qty.ref.syn]
    operator/=
    operator<=>
    quantity, [qty.cmp]
    quantity_point, [qty.pt.cmp]
    symbol_text, [qty.sym.txt]
    operator=
    quantity, [qty.cons]
    operator==
    AssociatedUnit, [qty.ref.cmp]
    Dimension, [qty.dim.ops]
    point-origin-interface, [qty.pt.orig.ops]
    quantity, [qty.cmp]
    quantity_point, [qty.pt.cmp]
    QuantitySpec, [qty.spec.ops]
    reference, [qty.ref.cmp]
    symbol_text, [qty.sym.txt]
    UnitMagnitude, [qty.unit.mag.ops]
    operator[]
    QuantitySpec, [qty.spec.ops]

    P

    parts_per_million, [mp.units.core.syn]
    point-origin-interface
    operator==, [qty.pt.orig.ops]
    point_
    operator(), [qty.point]
    point_for
    quantity_point, [qty.pt.conv]
    PointOrigin
    same-absolute-point-origins, [qty.same.abs.pt.origs]
    PointOriginFor, [qty.pt.orig.concepts]
    portable
    symbol_text, [qty.sym.txt]
    pow
    Dimension, [qty.dim.ops]
    QuantitySpec, [qty.spec.ops]
    reference, [qty.ref.syn]
    pow
    UnitMagnitude, [qty.unit.mag.ops]
    PrefixableUnit, [qty.unit.concepts]
    prefixed_unit, [qty.prefixed.unit]

    Q

    Quantity, [qty.syn]
    quantity, [qty.syn]
    constructor, [qty.cons]
    force_in, [qty.conv]
    force_numerical_value_in, [qty.obs]
    is_eq_zero, [qty.val.cmp]
    is_gt_zero, [qty.val.cmp]
    is_gteq_zero, [qty.val.cmp]
    is_lt_zero, [qty.val.cmp]
    is_lteq_zero, [qty.val.cmp]
    is_neq_zero, [qty.val.cmp]
    numerical_value_in, [qty.obs]
    numerical_value_ref_in, [qty.obs]
    operator constructible_from<Rep>, [qty.conv.ops]
    operator QuantityLike, [qty.conv.ops]
    operator%, [qty.arith.ops]
    operator%=, [qty.assign.ops]
    operator*=, [qty.assign.ops]
    operator++, [qty.unary.ops]
    operator--, [qty.unary.ops]
    operator/=, [qty.assign.ops]
    operator<=>, [qty.cmp]
    operator=, [qty.cons]
    operator==, [qty.cmp]
    quantity_cast, [qty.non.mem.conv]
    value_cast, [qty.non.mem.conv]
    quantity
    quantity-spec-interface, [qty.spec.ops]
    quantity_cast
    quantity_point, [qty.pt.non.mem.conv]
    quantity_character, [mp.units.core.syn]
    quantity_from
    quantity_point, [qty.pt.obs]
    quantity_from_zero
    quantity_point, [qty.pt.obs]
    quantity_like_traits
    std​::​chrono​::​duration, [qty.chrono]
    quantity_point, [qty.pt.syn]
    constructor, [qty.pt.cons]
    force_in, [qty.pt.conv]
    operator QuantityPointLike, [qty.pt.conv.ops]
    operator++, [qty.pt.unary.ops]
    operator--, [qty.pt.unary.ops]
    operator<=>, [qty.pt.cmp]
    operator==, [qty.pt.cmp]
    point_for, [qty.pt.conv]
    quantity_cast, [qty.pt.non.mem.conv]
    quantity_from, [qty.pt.obs]
    quantity_from_zero, [qty.pt.obs]
    quantity_ref_from, [qty.pt.obs]
    quantity_point_like_traits
    std​::​chrono​::​time_point, [qty.chrono]
    quantity_ref_from
    quantity_point, [qty.pt.obs]
    quantity_spec, [named.qty]
    QuantityLike, [qty.like]
    QuantityOf, [qty.syn]
    QuantityPoint, [qty.pt.syn]
    QuantityPointLike, [qty.pt.like]
    QuantityPointOf, [qty.pt.syn]
    QuantitySpec
    castable, [qty.spec.conv]
    clone-kind-of, [qty.spec.utils]
    explicitly_convertible, [qty.spec.conv]
    get-common-base, [qty.get.common.base]
    get-kind-tree-root, [qty.get.kind]
    get_common_quantity_spec, [get.common.qty.spec]
    get_kind, [qty.get.kind]
    implicitly_convertible, [qty.spec.conv]
    interconvertible, [qty.spec.conv]
    is-child-of, [qty.is.child.of]
    make-reference, [qty.spec.utils]
    operator(), [qty.spec.ops]
    operator*, [qty.spec.ops]
    operator/, [qty.spec.ops]
    operator==, [qty.spec.ops]
    operator[], [qty.spec.ops]
    remove-kind, [qty.spec.utils]
    QuantitySpec, [qty.spec.concepts]
    QuantitySpecOf, [qty.spec.concepts]

    R

    ratio, [qty.ratio]
    common-ratio, [qty.ratio]
    constructor, [qty.ratio]
    is-integral, [qty.ratio]
    operator*, [qty.ratio]
    operator+, [qty.ratio]
    operator-, [qty.ratio]
    operator/, [qty.ratio]
    operator<=>, [qty.ratio]
    operator==, [qty.ratio]
    Reference
    default_point_origin, [qty.def.pt.orig]
    operator*, [qty.ref.ops]
    operator/, [qty.ref.ops]
    reference, [qty.ref.syn]
    convertible, [qty.ref.cmp]
    get_common_reference, [qty.ref.obs]
    get_quantity_spec, [qty.ref.obs]
    get_unit, [qty.ref.obs]
    inverse, [qty.ref.syn]
    operator*, [qty.ref.syn]
    operator/, [qty.ref.syn]
    operator==, [qty.ref.cmp]
    relative_point_origin, [qty.rel.pt.orig]
    remove-kind
    QuantitySpec, [qty.spec.utils]
    Representation
    operator*, [qty.ref.ops]
    Representation, [qty.rep.concepts]
    representation_values, [qty.val.traits]
    RepresentationOf, [qty.rep.concepts]

    S

    same-absolute-point-origins
    scaled_unit, [qty.scaled.unit]
    space_before_unit_symbol, [qty.unit.traits]
    sqrt
    Dimension, [qty.dim.ops]
    QuantitySpec, [qty.spec.ops]
    reference, [qty.ref.syn]
    square
    std​::​common_type
    sudo-cast
    quantity_point, [qty.pt.non.mem.conv]
    symbol_text, [qty.sym.txt]
    constructor, [qty.sym.txt]
    operator+, [qty.sym.txt]
    operator<=>, [qty.sym.txt]
    operator==, [qty.sym.txt]
    portable, [qty.sym.txt]

    T

    treat_as_floating_point, [qty.fp.traits]
    type-less-impl, [qty.sym.expr.algos]

    U

    Unit
    convertible, [qty.unit.cmp]
    equivalent, [qty.unit.cmp]
    get-canonical-unit, [qty.canon.unit]
    get_common_unit, [qty.unit.obs]
    has-associated-quantity, [assoc.qty]
    make-reference, [qty.spec.utils]
    operator*, [qty.unit.ops]
    operator/, [qty.unit.ops]
    operator==, [qty.unit.cmp]
    unit_symbol, [qty.unit.sym.fmt]
    unit_symbol_to, [qty.unit.sym.fmt]
    unit-interface, [qty.unit.ops]
    unit-magnitude, [qty.unit.mag.types]
    unit_symbol
    unit_symbol_formatting, [mp.units.core.syn]
    unit_symbol_separator, [mp.units.core.syn]
    unit_symbol_solidus, [mp.units.core.syn]
    unit_symbol_to
    UnitMagnitude
    common-magnitude, [qty.unit.mag.utils]
    is-positive-integral-power, [qty.unit.mag.utils]
    operator==, [qty.unit.mag.ops]
    utf8
    symbol_text, [qty.sym.txt]

    V

    value_cast
    quantity_point, [qty.pt.non.mem.conv]

    Z

    zero
    quantity, [qty.static]
    zeroth_point_origin, [mp.units.core.syn]
    zeroth_point_origin_, [qty.zeroth.pt.orig]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/mp.units.core.syn.html b/HEAD/api_reference/gen/mp.units.core.syn.html index 6925417c..ac3b61e7 100644 --- a/HEAD/api_reference/gen/mp.units.core.syn.html +++ b/HEAD/api_reference/gen/mp.units.core.syn.html @@ -1,68 +1,628 @@ -[mp.units.core.syn]

    5 Quantities library [qties]

    5.3 Module mp_units.core synopsis [mp.units.core.syn]

    export module mp_units.core; +[mp.units.core.syn]

    5 Quantities and units library [quantities]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.2 Module mp_units.core synopsis [mp.units.core.syn]

    // mostly freestanding +export module mp_units.core; import std; export namespace mp_units { -export enum class quantity_character { scalar, vector, tensor }; +// [qty.utils], utilities -// [qty.traits], traits +// [qty.sym.txt], symbol text -template<typename Rep> -constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>; +enum class character_set : std::int8_t { utf8, portable, default_character_set = utf8 }; -template<typename Rep> -constexpr bool is_scalar = - std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>); +template<std::size_t N, std::size_t M> +class symbol_text; -template<typename Rep> -constexpr bool is_vector = false; +// [qty.sym.expr], symbolic expressions -template<typename Rep> -constexpr bool is_tensor = false; +// [qty.sym.expr.types], types -template<typename Rep> -struct quantity_values; +template<typename T, typename... Ts> +struct per; + +template<typename F, int Num, int... Den> + requires see below +struct power; + +// [qty.ref], reference + +// [qty.dim], dimension + +// [qty.dim.concepts], concepts template<typename T> -struct quantity_like_traits; +concept Dimension = see below; + +template<typename T, auto D> +concept DimensionOf = see below; + +// [qty.dim.types], types + +template<symbol_text Symbol> +struct base_dimension; + +template<SymbolicConstant... Expr> +struct derived_dimension; + +struct dimension_one; +inline constexpr dimension_one dimension_one{}; + +// [qty.dim.ops], operations + +consteval Dimension auto inverse(Dimension auto d); + +template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +consteval Dimension auto sqrt(Dimension auto d); +consteval Dimension auto cbrt(Dimension auto d); + +// [qty.dim.sym.fmt], symbol formatting + +struct dimension_symbol_formatting { + character_set char_set = character_set::default_character_set; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); + +template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); + +// [qty.spec], quantity specification + +// [qty.spec.concepts], concepts template<typename T> -struct quantity_point_like_traits; +concept QuantitySpec = see below; -// [qty.concepts], concepts +template<typename T, auto QS> +concept QuantitySpecOf = see below; -template<typename T> -concept some_reference = template_of(^std::remove_cvref_t<T>) == ^reference; +// [qty.spec.types], types -template<typename T> -concept representation = see below; +// [named.qty], named -template<typename T, quantity_character Ch> -concept representation_of = see below; - -template<typename T> -concept some_quantity_spec = see below; - -// [qty.types], types +struct is_kind; +inline constexpr is_kind is_kind{}; template<auto...> -struct quantity_spec; // not defined +struct quantity_spec; // not defined -template<auto Q> -struct kind_of_; // not defined +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...>; -template<unspecified... Expr> +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...>; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...>; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<QS, Eq, Args...>; + +// [derived.qty], derived + +template<SymbolicConstant... Expr> struct derived_quantity_spec; -// [qty.type], class template quantity -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> +// [dimless.qty], base quantity of dimension one + +struct dimensionless; +inline constexpr dimensionless dimensionless{}; + +// [kind.of.qty], kind of + +template<QuantitySpec Q> + requires see below +struct kind_of_; +template<QuantitySpec auto Q> + requires requires { typename kind_of_<decltype(Q)>; } +inline constexpr kind_of_<decltype(Q)> kind_of{}; + +// [qty.spec.ops], operations + +consteval QuantitySpec auto inverse(QuantitySpec auto q); + +template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +consteval QuantitySpec auto sqrt(QuantitySpec auto q); +consteval QuantitySpec auto cbrt(QuantitySpec auto q); + +// [qty.spec.hier.algos], hierarchy algorithms + +// [qty.spec.conv], conversion + +consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); + +// [qty.get.kind], get_kind + +template<QuantitySpec Q> +consteval see below get_kind(Q); + +// [get.common.qty.spec], get_common_quantity_spec + +consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; + +// [qty.unit], unit + +// [qty.unit.mag], magnitude + +// [qty.unit.mag.concepts], concepts + +template<typename T> +concept MagConstant = see below; + +template<typename T> +concept UnitMagnitude = see below; + +// [qty.unit.mag.types], types + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant; + +// [qty.unit.mag.ops], operations + +template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; + +template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; + +template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = see below; + +// constants + +inline constexpr struct pi final : + mag_constant<{u8"\u03C0" /* U+03c0 GREEK SMALL LETTER PI */, "pi"}, + std::numbers::pi_v<long double>> { +} pi; + +inline constexpr auto \u03C0 /* U+03c0 GREEK SMALL LETTER PI */ = pi; + +// [qty.unit.traits], traits + +template<Unit auto U> +constexpr bool space_before_unit_symbol = true; + +template<> +inline constexpr bool space_before_unit_symbol<one> = false; + +// [qty.unit.concepts], concepts + +template<typename T> +concept Unit = see below; + +template<typename T> +concept PrefixableUnit = see below; + +template<typename T> +concept AssociatedUnit = see below; + +template<typename U, auto QS> +concept UnitOf = see below; + +// [qty.unit.types], types + +// [qty.scaled.unit], scaled + +template<UnitMagnitude auto M, Unit U> + requires see below +struct scaled_unit; + +// [qty.named.unit], named + +template<symbol_text Symbol, auto...> +struct named_unit; // not defined + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, QS>; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, QS, PO>; + +template<symbol_text Symbol> + requires see below +struct named_unit<Symbol>; + +template<symbol_text Symbol, Unit auto U> + requires see below +struct named_unit<Symbol, U>; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, PO>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, U, QS>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, QS, PO>; + +// [qty.prefixed.unit], prefixed + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires see below +struct prefixed_unit; + +// [qty.common.unit], common + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit; + +// [qty.derived.unit], derived + +template<SymbolicConstant... Expr> +struct derived_unit; + +// [qty.unit.one], one + +struct one; +inline constexpr one one{}; + +// named derived units of a quantity of dimension one + +inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> { +} percent; + +inline constexpr struct per_mille final : + named_unit<symbol_text{u8"\u2030" /* U+2030 PER MILLE SIGN */, "%o"}, + mag_ratio<1, 1000> * one> { +} per_mille; + +inline constexpr struct parts_per_million final : + named_unit<"ppm", mag_ratio<1, 1'000'000> * one> { +} parts_per_million; + +inline constexpr auto ppm = parts_per_million; + +// [qty.unit.ops], operations + +consteval Unit auto inverse(Unit auto u); + +template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires see below +consteval Unit auto pow(U u); +consteval Unit auto sqrt(Unit auto u); +consteval Unit auto cbrt(Unit auto u); +consteval Unit auto square(Unit auto u); +consteval Unit auto cubic(Unit auto u); + +// [qty.unit.cmp], comparison + +template<Unit From, Unit To> +consteval bool convertible(From from, To to); + +// [qty.unit.obs], observers + +consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +consteval Unit auto get_unit(AssociatedUnit auto u); + +consteval Unit auto get_common_unit(Unit auto... us) + requires see below; + +// [qty.unit.sym.fmt], symbol formatting + +enum class unit_symbol_solidus : std::int8_t { + one_denominator, + always, + never, + default_denominator = one_denominator +}; + +enum class unit_symbol_separator : std::int8_t { + space, + half_high_dot, + default_separator = space +}; + +struct unit_symbol_formatting { + character_set char_set = character_set::default_character_set; + unit_symbol_solidus solidus = unit_symbol_solidus::default_denominator; + unit_symbol_separator separator = unit_symbol_separator::default_separator; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); + +template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); + +// [qty.ref.concepts], concepts + +template<typename T> +concept Reference = see below; + +template<typename T, auto QS> +concept ReferenceOf = see below; + +// [qty.ref.syn], class template reference + +template<QuantitySpec Q, Unit U> +struct reference; + +// [qty.ref.ops], operations + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; + +// [qty.ref.obs], observers + +template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); + +template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); + +consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; + +template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; + +// [qty.rep], representation + +enum class quantity_character { scalar, complex, vector, tensor }; + +// [qty.rep.traits], traits + +// [qty.fp.traits], floating-point + +template<typename Rep> +constexpr bool treat_as_floating_point = see below; + +// [qty.char.traits], quantity character + +template<typename T> +constexpr bool disable_scalar = false; +template<> +inline constexpr bool disable_scalar<bool> = true; +template<typename T> +constexpr bool disable_scalar<std::complex<T>> = true; + +template<typename T> +constexpr bool disable_complex = false; + +template<typename T> +constexpr bool disable_vector = false; + +// [qty.val.traits], values + +template<typename Rep> +struct representation_values; + +// [qty.rep.cpos], customization point objects + +inline namespace unspecified { + +inline constexpr unspecified real = unspecified; +inline constexpr unspecified imag = unspecified; +inline constexpr unspecified modulus = unspecified; + +inline constexpr unspecified magnitude = unspecified; + +} + +// [qty.rep.concepts], concepts + +template<typename T> +concept Representation = see below; + +template<typename T, quantity_character Ch> +concept RepresentationOf = see below; + +// [qty], quantity + +// [qty.like], interoperability + +template<typename T> +struct quantity_like_traits; // not defined + +template<typename T> +concept QuantityLike = see below; + +// [qty.syn], class template quantity + +template<typename T> +concept Quantity = see below; + +template<typename Q, auto QS> +concept QuantityOf = see below; + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> class quantity; -// [qty.point.type], class template quantity_point -template<unspecified> +// [qty.delta], construction helper delta + +template<Reference R> +struct delta_; + +template<Reference auto R> +constexpr delta_<decltype(R)> delta{}; + +// [qty.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Representation ToRep, see below> + requires see below +constexpr quantity<see below, ToRep> value_cast(see below q); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr Quantity auto value_cast(see below q); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Quantity ToQ, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr Quantity auto quantity_cast(see below q); + +} + +// [qty.common.type], std​::​common_type specializations + +template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires see below +struct std::common_type<Q1, Q2>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires see below +struct std::common_type<Q, Value>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires requires { typename std::common_type<Q, Value>; } +struct std::common_type<Value, Q> : std::common_type<Q, Value> {}; + +namespace mp_units { + +// [qty.pt], quantity point + +// [qty.pt.orig], point origin + +// [qty.pt.orig.concepts], concepts + +template<typename T> +concept PointOrigin = see below; + +template<typename T, auto QS> +concept PointOriginFor = see below; + +// [qty.pt.orig.types], types + +// [qty.abs.pt.orig], absolute + +template<QuantitySpec auto QS> +struct absolute_point_origin; + +// [qty.rel.pt.orig], relative + +template<QuantityPoint auto QP> +struct relative_point_origin; + +// [qty.zeroth.pt.orig], zeroth + +template<QuantitySpec auto QS> +struct zeroth_point_origin_; + +template<QuantitySpec auto QS> +constexpr zeroth_point_origin_<QS> zeroth_point_origin{}; + +// [qty.def.pt.orig], default + +template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); + +// [qty.pt.like], interoperability + +template<typename T> +struct quantity_point_like_traits; // not defined + +template<typename T> +concept QuantityPointLike = see below; + +// [qty.pt.syn], class template quantity_point + +template<typename T> +concept QuantityPoint = see below; + +template<typename QP, auto V> +concept QuantityPointOf = see below; + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> class quantity_point; +// [qty.point], construction helper point + +template<Reference R> +struct point_; + +template<Reference auto R> +constexpr point_<decltype(R)> point{}; + +// [qty.pt.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Representation ToRep, see below> + requires see below +constexpr quantity_point<see below, see below, ToRep> value_cast(see below qp); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Quantity ToQ, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantityPoint ToQP, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr QuantityPoint auto quantity_cast(see below qp); + }
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/mp.units.syn.html b/HEAD/api_reference/gen/mp.units.syn.html index 1ec18555..6946d4c5 100644 --- a/HEAD/api_reference/gen/mp.units.syn.html +++ b/HEAD/api_reference/gen/mp.units.syn.html @@ -1,4 +1,4 @@ -[mp.units.syn]

    5 Quantities library [qties]

    5.2 Module mp_units synopsis [mp.units.syn]

    export module mp_units; +[mp.units.syn]

    5 Quantities and units library [quantities]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.1 Module mp_units synopsis [mp.units.syn]

    export module mp_units; export import mp_units.core; export import mp_units.systems; diff --git a/HEAD/api_reference/gen/mp.units.syns.html b/HEAD/api_reference/gen/mp.units.syns.html new file mode 100644 index 00000000..0d5a6fd3 --- /dev/null +++ b/HEAD/api_reference/gen/mp.units.syns.html @@ -0,0 +1,654 @@ +[mp.units.syns]

    5 Quantities and units library [quantities]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.1 Module mp_units synopsis [mp.units.syn]

    export module mp_units; + +export import mp_units.core; +export import mp_units.systems; +

    5.2.2 Module mp_units.core synopsis [mp.units.core.syn]

    // mostly freestanding +export module mp_units.core; + +import std; + +export namespace mp_units { + +// [qty.utils], utilities + +// [qty.sym.txt], symbol text + +enum class character_set : std::int8_t { utf8, portable, default_character_set = utf8 }; + +template<std::size_t N, std::size_t M> +class symbol_text; + +// [qty.sym.expr], symbolic expressions + +// [qty.sym.expr.types], types + +template<typename T, typename... Ts> +struct per; + +template<typename F, int Num, int... Den> + requires see below +struct power; + +// [qty.ref], reference + +// [qty.dim], dimension + +// [qty.dim.concepts], concepts + +template<typename T> +concept Dimension = see below; + +template<typename T, auto D> +concept DimensionOf = see below; + +// [qty.dim.types], types + +template<symbol_text Symbol> +struct base_dimension; + +template<SymbolicConstant... Expr> +struct derived_dimension; + +struct dimension_one; +inline constexpr dimension_one dimension_one{}; + +// [qty.dim.ops], operations + +consteval Dimension auto inverse(Dimension auto d); + +template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +consteval Dimension auto sqrt(Dimension auto d); +consteval Dimension auto cbrt(Dimension auto d); + +// [qty.dim.sym.fmt], symbol formatting + +struct dimension_symbol_formatting { + character_set char_set = character_set::default_character_set; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); + +template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); + +// [qty.spec], quantity specification + +// [qty.spec.concepts], concepts + +template<typename T> +concept QuantitySpec = see below; + +template<typename T, auto QS> +concept QuantitySpecOf = see below; + +// [qty.spec.types], types + +// [named.qty], named + +struct is_kind; +inline constexpr is_kind is_kind{}; + +template<auto...> +struct quantity_spec; // not defined + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...>; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...>; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...>; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<QS, Eq, Args...>; + +// [derived.qty], derived + +template<SymbolicConstant... Expr> +struct derived_quantity_spec; + +// [dimless.qty], base quantity of dimension one + +struct dimensionless; +inline constexpr dimensionless dimensionless{}; + +// [kind.of.qty], kind of + +template<QuantitySpec Q> + requires see below +struct kind_of_; +template<QuantitySpec auto Q> + requires requires { typename kind_of_<decltype(Q)>; } +inline constexpr kind_of_<decltype(Q)> kind_of{}; + +// [qty.spec.ops], operations + +consteval QuantitySpec auto inverse(QuantitySpec auto q); + +template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +consteval QuantitySpec auto sqrt(QuantitySpec auto q); +consteval QuantitySpec auto cbrt(QuantitySpec auto q); + +// [qty.spec.hier.algos], hierarchy algorithms + +// [qty.spec.conv], conversion + +consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); + +// [qty.get.kind], get_kind + +template<QuantitySpec Q> +consteval see below get_kind(Q); + +// [get.common.qty.spec], get_common_quantity_spec + +consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; + +// [qty.unit], unit + +// [qty.unit.mag], magnitude + +// [qty.unit.mag.concepts], concepts + +template<typename T> +concept MagConstant = see below; + +template<typename T> +concept UnitMagnitude = see below; + +// [qty.unit.mag.types], types + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant; + +// [qty.unit.mag.ops], operations + +template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; + +template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; + +template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = see below; + +// constants + +inline constexpr struct pi final : + mag_constant<{u8"\u03C0" /* U+03c0 GREEK SMALL LETTER PI */, "pi"}, + std::numbers::pi_v<long double>> { +} pi; + +inline constexpr auto \u03C0 /* U+03c0 GREEK SMALL LETTER PI */ = pi; + +// [qty.unit.traits], traits + +template<Unit auto U> +constexpr bool space_before_unit_symbol = true; + +template<> +inline constexpr bool space_before_unit_symbol<one> = false; + +// [qty.unit.concepts], concepts + +template<typename T> +concept Unit = see below; + +template<typename T> +concept PrefixableUnit = see below; + +template<typename T> +concept AssociatedUnit = see below; + +template<typename U, auto QS> +concept UnitOf = see below; + +// [qty.unit.types], types + +// [qty.scaled.unit], scaled + +template<UnitMagnitude auto M, Unit U> + requires see below +struct scaled_unit; + +// [qty.named.unit], named + +template<symbol_text Symbol, auto...> +struct named_unit; // not defined + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, QS>; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, QS, PO>; + +template<symbol_text Symbol> + requires see below +struct named_unit<Symbol>; + +template<symbol_text Symbol, Unit auto U> + requires see below +struct named_unit<Symbol, U>; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, PO>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, U, QS>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, QS, PO>; + +// [qty.prefixed.unit], prefixed + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires see below +struct prefixed_unit; + +// [qty.common.unit], common + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit; + +// [qty.derived.unit], derived + +template<SymbolicConstant... Expr> +struct derived_unit; + +// [qty.unit.one], one + +struct one; +inline constexpr one one{}; + +// named derived units of a quantity of dimension one + +inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> { +} percent; + +inline constexpr struct per_mille final : + named_unit<symbol_text{u8"\u2030" /* U+2030 PER MILLE SIGN */, "%o"}, + mag_ratio<1, 1000> * one> { +} per_mille; + +inline constexpr struct parts_per_million final : + named_unit<"ppm", mag_ratio<1, 1'000'000> * one> { +} parts_per_million; + +inline constexpr auto ppm = parts_per_million; + +// [qty.unit.ops], operations + +consteval Unit auto inverse(Unit auto u); + +template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires see below +consteval Unit auto pow(U u); +consteval Unit auto sqrt(Unit auto u); +consteval Unit auto cbrt(Unit auto u); +consteval Unit auto square(Unit auto u); +consteval Unit auto cubic(Unit auto u); + +// [qty.unit.cmp], comparison + +template<Unit From, Unit To> +consteval bool convertible(From from, To to); + +// [qty.unit.obs], observers + +consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +consteval Unit auto get_unit(AssociatedUnit auto u); + +consteval Unit auto get_common_unit(Unit auto... us) + requires see below; + +// [qty.unit.sym.fmt], symbol formatting + +enum class unit_symbol_solidus : std::int8_t { + one_denominator, + always, + never, + default_denominator = one_denominator +}; + +enum class unit_symbol_separator : std::int8_t { + space, + half_high_dot, + default_separator = space +}; + +struct unit_symbol_formatting { + character_set char_set = character_set::default_character_set; + unit_symbol_solidus solidus = unit_symbol_solidus::default_denominator; + unit_symbol_separator separator = unit_symbol_separator::default_separator; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); + +template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); + +// [qty.ref.concepts], concepts + +template<typename T> +concept Reference = see below; + +template<typename T, auto QS> +concept ReferenceOf = see below; + +// [qty.ref.syn], class template reference + +template<QuantitySpec Q, Unit U> +struct reference; + +// [qty.ref.ops], operations + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; + +// [qty.ref.obs], observers + +template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); + +template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); + +consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; + +template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; + +// [qty.rep], representation + +enum class quantity_character { scalar, complex, vector, tensor }; + +// [qty.rep.traits], traits + +// [qty.fp.traits], floating-point + +template<typename Rep> +constexpr bool treat_as_floating_point = see below; + +// [qty.char.traits], quantity character + +template<typename T> +constexpr bool disable_scalar = false; +template<> +inline constexpr bool disable_scalar<bool> = true; +template<typename T> +constexpr bool disable_scalar<std::complex<T>> = true; + +template<typename T> +constexpr bool disable_complex = false; + +template<typename T> +constexpr bool disable_vector = false; + +// [qty.val.traits], values + +template<typename Rep> +struct representation_values; + +// [qty.rep.cpos], customization point objects + +inline namespace unspecified { + +inline constexpr unspecified real = unspecified; +inline constexpr unspecified imag = unspecified; +inline constexpr unspecified modulus = unspecified; + +inline constexpr unspecified magnitude = unspecified; + +} + +// [qty.rep.concepts], concepts + +template<typename T> +concept Representation = see below; + +template<typename T, quantity_character Ch> +concept RepresentationOf = see below; + +// [qty], quantity + +// [qty.like], interoperability + +template<typename T> +struct quantity_like_traits; // not defined + +template<typename T> +concept QuantityLike = see below; + +// [qty.syn], class template quantity + +template<typename T> +concept Quantity = see below; + +template<typename Q, auto QS> +concept QuantityOf = see below; + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity; + +// [qty.delta], construction helper delta + +template<Reference R> +struct delta_; + +template<Reference auto R> +constexpr delta_<decltype(R)> delta{}; + +// [qty.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Representation ToRep, see below> + requires see below +constexpr quantity<see below, ToRep> value_cast(see below q); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr Quantity auto value_cast(see below q); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Quantity ToQ, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr Quantity auto quantity_cast(see below q); + +} + +// [qty.common.type], std​::​common_type specializations + +template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires see below +struct std::common_type<Q1, Q2>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires see below +struct std::common_type<Q, Value>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires requires { typename std::common_type<Q, Value>; } +struct std::common_type<Value, Q> : std::common_type<Q, Value> {}; + +namespace mp_units { + +// [qty.pt], quantity point + +// [qty.pt.orig], point origin + +// [qty.pt.orig.concepts], concepts + +template<typename T> +concept PointOrigin = see below; + +template<typename T, auto QS> +concept PointOriginFor = see below; + +// [qty.pt.orig.types], types + +// [qty.abs.pt.orig], absolute + +template<QuantitySpec auto QS> +struct absolute_point_origin; + +// [qty.rel.pt.orig], relative + +template<QuantityPoint auto QP> +struct relative_point_origin; + +// [qty.zeroth.pt.orig], zeroth + +template<QuantitySpec auto QS> +struct zeroth_point_origin_; + +template<QuantitySpec auto QS> +constexpr zeroth_point_origin_<QS> zeroth_point_origin{}; + +// [qty.def.pt.orig], default + +template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); + +// [qty.pt.like], interoperability + +template<typename T> +struct quantity_point_like_traits; // not defined + +template<typename T> +concept QuantityPointLike = see below; + +// [qty.pt.syn], class template quantity_point + +template<typename T> +concept QuantityPoint = see below; + +template<typename QP, auto V> +concept QuantityPointOf = see below; + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point; + +// [qty.point], construction helper point + +template<Reference R> +struct point_; + +template<Reference auto R> +constexpr point_<decltype(R)> point{}; + +// [qty.pt.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Representation ToRep, see below> + requires see below +constexpr quantity_point<see below, see below, ToRep> value_cast(see below qp); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Quantity ToQ, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantityPoint ToQP, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr QuantityPoint auto quantity_cast(see below qp); + +} +

    5.2.3 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; + +export import mp_units.core; +import std; + +export namespace mp_units { + +// [qty.chrono], std​::​chrono interoperability + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>>; + +template<typename Clock> +struct chrono_point_origin_; +template<typename Clock> +constexpr chrono_point_origin_<Clock> chrono_point_origin{}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>>; + +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/mp.units.systems.syn.html b/HEAD/api_reference/gen/mp.units.systems.syn.html index 5bce2243..0e9cbff4 100644 --- a/HEAD/api_reference/gen/mp.units.systems.syn.html +++ b/HEAD/api_reference/gen/mp.units.systems.syn.html @@ -1,9 +1,23 @@ -[mp.units.systems.syn]

    5 Quantities library [qties]

    5.4 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; +[mp.units.systems.syn]

    5 Quantities and units library [quantities]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.3 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; export import mp_units.core; import std; export namespace mp_units { +// [qty.chrono], std​::​chrono interoperability + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>>; + +template<typename Clock> +struct chrono_point_origin_; +template<typename Clock> +constexpr chrono_point_origin_<Clock> chrono_point_origin{}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>>; + }
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/named.qty.html b/HEAD/api_reference/gen/named.qty.html new file mode 100644 index 00000000..5c3b000a --- /dev/null +++ b/HEAD/api_reference/gen/named.qty.html @@ -0,0 +1,65 @@ +[named.qty]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.1 Named [named.qty]

    namespace mp_units { + +struct is_kind {}; + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr BaseDimension auto dimension = Dim; + static constexpr quantity_character character = see below; +}; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = parent.equation; // exposition only, present only + // if the qualified-id parent.equation is valid and denotes an object + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> + requires QuantitySpecExplicitlyConvertibleTo<Eq, QS> +struct quantity_spec<QS, Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +} +
    A named quantity is a type that models NamedQuantitySpec.
    A specialization of quantity_spec is used as a base type when defining a named quantity.
    In the following descriptions, let Q be a named quantity defined with an alluded signature.
    The identifier of Q represents its quantity name (IEC 60050, 112-01-02).
    Let Ch be an enumerator value of quantity_character.
    The possible arguments to quantity_spec are +
    • ,
    • ,
    • , and
    • .
    If the first argument is a base quantity dimension, +then Q is that base quantity (IEC 60050, 112-01-08).
    If an argument is a quantity calculus (IEC 60050, 112-01-30) C, +then Q is implicitly convertible from C.
    If the first argument is a named quantity, +then Q is of its kind (IEC 60050, 112-01-04).
    The member character represents +the set of the numerical value of Q ([qty.char.traits]) +and is equal to +
    • Ch if specified,
    • otherwise, quantity_character​::​scalar for the first signature, and
    • otherwise, (BC).character, +where BC is the argument preceding Ch in the signatures above.
    is_kind specifies Q to start a new hierarchy tree of a kind.
    Optional arguments may appear in any order.
    [Example 1: // The first signature defines a base quantity. +inline constexpr struct length final : quantity_spec<dim_length> { +} length; // Length is a base quantity. + +// The second signature defines a derived quantity. +inline constexpr struct area final : quantity_spec<pow<2>(length)> { +} area; // An area equals length by length. + +// The third and fourth signatures add a leaf to a hierarchy of kinds. +inline constexpr struct width final : quantity_spec<length> { +} width; // Width is a kind of length. + +// The fourth signature also refines the calculus required for implicit conversions. +inline constexpr struct angular_measure final : + quantity_spec<dimensionless, arc_length / radius, is_kind> { +} angular_measure; // Requires an arc length per radius, not just any quantity of dimension one. + — end example]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qties.html b/HEAD/api_reference/gen/qties.html deleted file mode 100644 index 28a24b5a..00000000 --- a/HEAD/api_reference/gen/qties.html +++ /dev/null @@ -1,144 +0,0 @@ -[qties]

    5 Quantities library [qties]

    5.1 Summary [qties.summary]

    This Clause describes components for dealing with quantities, -as summarized in Table 3.
    Table 3: Quantities library summary [tab:qties.summary]
    Subclause
    Module
    Helpers
    mp_units.core
    Traits
    Concepts
    Types
    Compatibility
    Dimension one
    Systems
    mp_units.systems
    std​::​chrono compatibility

    5.2 Module mp_units synopsis [mp.units.syn]

    export module mp_units; - -export import mp_units.core; -export import mp_units.systems; -

    5.3 Module mp_units.core synopsis [mp.units.core.syn]

    export module mp_units.core; - -import std; - -export namespace mp_units { - -export enum class quantity_character { scalar, vector, tensor }; - -// [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; - -// [qty.concepts], concepts - -template<typename T> -concept some_reference = template_of(^std::remove_cvref_t<T>) == ^reference; - -template<typename T> -concept representation = see below; - -template<typename T, quantity_character Ch> -concept representation_of = see below; - -template<typename T> -concept some_quantity_spec = see below; - -// [qty.types], types - -template<auto...> -struct quantity_spec; // not defined - -template<auto Q> -struct kind_of_; // not defined - -template<unspecified... Expr> -struct derived_quantity_spec; - -// [qty.type], class template quantity -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> -class quantity; - -// [qty.point.type], class template quantity_point -template<unspecified> -class quantity_point; - -} -

    5.4 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; - -export import mp_units.core; -import std; - -export namespace mp_units { - -} -

    5.5 Helpers [qty.helpers]

    consteval bool converts-to-base-subobject-of(std::meta type, std::meta template_name); -
    Preconditions: is_type(type) && is_template(template_name) is true.
    Returns: true if -[:type:] has an unambiguous and accessible base -that is a specialization of [:template_name:], and -false otherwise.

    5.6 Traits [qty.traits]

    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; -
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), -users may specialize is_scalar, is_vector, and is_tensor to true -for cv-unqualified program-defined types -which respectively represent -a scalar (IEC 60050, 102-02-18), -a vector (IEC 60050, 102-03-04), and -a tensor, -and false for types which respectively do not.

    5.7 Concepts [qty.concepts]

    export template<typename T> -concept representation = - (is_scalar<T> || is_vector<T> || is_tensor<T>)&&std::regular<T> && scalable<T>; -
    export template<typename T, quantity_character Ch> -concept representation_of = - representation<T> && ((Ch == quantity_character::scalar && is_scalar<T>) || - (Ch == quantity_character::vector && is_vector<T>) || - (Ch == quantity_character::tensor && is_tensor<T>)); -
    template<typename T> -concept named-quantity-spec = - (converts-to-base-subobject-of(^T, ^quantity_spec) && template_of(^T) != ^kind_of_); - -template<typename T> -concept some_quantity_spec = - named-quantity-spec<T> || - detail::IntermediateDerivedQuantitySpec<T> || - template_of(^T) == ^kind_of; -

    5.8 Types [qty.types]

    5.8.1 General [qty.types.general]

    A quantity type -is a type Q -that is a specialization of quantity or quantity_point.
    Q represents a quantity (IEC 60050, 112-01-01) -with Q​::​rep as its number -and Q​::​reference as its reference.
    Q is a structural type (N4971, [temp.param]) -if Q​::​rep is a structural type.
    Each class template defined in subclause [qty.types] -has data members and special members specified below, and -has no base classes or members other than those specified.

    5.8.2 Class template quantity [qty.type]

    namespace mp_units { - -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> -class quantity { unspecified }; - -} -
    Let Q be a specialization of quantity.

    5.8.3 Class template quantity_point [qty.point.type]

    namespace mp_units { - -export template<unspecified> -class quantity_point { unspecified }; - -} -
    A quantity point type is a specialization of quantity_point.
    Let Q be a quantity point type.
    Q​::​point_origin represents -the origin point of a position vector (IEC 60050, 102-03-15).
    • If Rep is a scalar, -Q represents the scalar quantity (IEC 60050, 102-02-19) -of a position vector.
    • If Rep is a vector, -Q represents a position vector.

    5.9 Compatibility [qty.compat]

    5.10 Dimension one [qty.one]

    5.12 std​::​chrono compatibility [qty.chrono]

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qties.summary.html b/HEAD/api_reference/gen/qties.summary.html deleted file mode 100644 index 25909756..00000000 --- a/HEAD/api_reference/gen/qties.summary.html +++ /dev/null @@ -1,2 +0,0 @@ -[qties.summary]

    5 Quantities library [qties]

    5.1 Summary [qties.summary]

    This Clause describes components for dealing with quantities, -as summarized in Table 3.
    Table 3: Quantities library summary [tab:qties.summary]
    Subclause
    Module
    Helpers
    mp_units.core
    Traits
    Concepts
    Types
    Compatibility
    Dimension one
    Systems
    mp_units.systems
    std​::​chrono compatibility
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.abs.pt.orig.html b/HEAD/api_reference/gen/qty.abs.pt.orig.html new file mode 100644 index 00000000..d11d29dd --- /dev/null +++ b/HEAD/api_reference/gen/qty.abs.pt.orig.html @@ -0,0 +1,10 @@ +[qty.abs.pt.orig]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.1 Absolute [qty.abs.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct absolute_point_origin : point-origin-interface { + static constexpr QuantitySpec auto quantity-spec = QS; // exposition only +}; + +} +
    An absolute origin is an origin +chosen by convention and not defined in terms of another origin.
    A specialization of absolute_point_origin is used as a base type when defining an absolute origin.
    QS is the quantity the origin represents.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.arith.ops.html b/HEAD/api_reference/gen/qty.arith.ops.html new file mode 100644 index 00000000..0988fa52 --- /dev/null +++ b/HEAD/api_reference/gen/qty.arith.ops.html @@ -0,0 +1,74 @@ +[qty.arith.ops]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.11 Arithmetic operations [qty.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let F be the first argument to CommonlyInvocableQuantities.
    Preconditions: If @ is %, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +using ret = common-quantity-for<F, quantity, quantity<R2, Rep2>>; +const ret ret_lhs(lhs); +const ret ret_rhs(rhs); +return ::mp_units::quantity{ + ret_lhs.numerical_value_ref_in(ret::unit) @ ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; +
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); +
    Effects: Equivalent to: +return lhs @ ​::​mp_units​::​quantity{rhs};
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{lhs} @ rhs;
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{ + lhs.numerical_value_ref_in(unit) @ rhs.numerical_value_ref_in(rhs.unit), R @ R2}; +
    template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); +
    Preconditions: If @ is /, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs.numerical_value_ref_in(unit) @ rhs, R}; +
    template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); +template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> +friend constexpr Quantity auto operator/(const Value& lhs, const Q& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs @ rhs.numerical_value_ref_in(unit), ::mp_units::one @ R}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.assign.ops.html b/HEAD/api_reference/gen/qty.assign.ops.html new file mode 100644 index 00000000..0db40b0b --- /dev/null +++ b/HEAD/api_reference/gen/qty.assign.ops.html @@ -0,0 +1,43 @@ +[qty.assign.ops]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.10 Compound assignment operations [qty.assign.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is %=, then is_neq_zero(rhs) is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.in(lhs.unit).numerical-value.
    Returns: std​::​forward<Q>(lhs).
    Remarks: Let C be +
    • (!treat_as_floating_point<rep>) if @ is %=, and
    • true otherwise.
    +The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && C && +requires(rep& a, const Rep2 b) { + { a @ b } -> std::same_as<rep&>; +} +
    Recommended practice: If equivalent(unit, get_unit(rhs.reference)) is true, +then the expression rhs.in(lhs.unit) is replaced with rhs.
    template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); +template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); +
    Preconditions: If @ is /=, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.
    Returns: std​::​forward<Q>(lhs).
    Remarks: The expression in the requires-clause is equivalent to: +(!Quantity<Value>) && requires(rep& a, const Value b) { + { a @ b } -> std::same_as<rep&>; +} +
    template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); +template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); +
    Effects: Equivalent to: +return std​::​forward<Q>(lhs) @ rhs.numerical-value;
    Remarks: The expression in the requires-clause is equivalent to: +(Q2::unit == ::mp_units::one) && ValuePreservingTo<typename Q2::rep, Rep> && +requires(rep& a, const Q2::rep b) { + { a @ b } -> std::same_as<rep&>; +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.canon.unit.html b/HEAD/api_reference/gen/qty.canon.unit.html new file mode 100644 index 00000000..8ac0ce53 --- /dev/null +++ b/HEAD/api_reference/gen/qty.canon.unit.html @@ -0,0 +1,11 @@ +[qty.canon.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.1 Canonical [qty.canon.unit]

    namespace mp_units { + +template<UnitMagnitude M, Unit U> +struct canonical-unit { // exposition only + M mag; + U reference_unit; +}; + +} +
    canonical-unit represents a unit expressed in terms of base units (IEC 60050, 112-01-18).
    [Note 1: 
    Other types representing units are equal only if they have the same type.
    canonical-unit is used to implement binary relations other than equality.
    — end note]
    reference_unit is simplified ([qty.sym.expr.algos]).
    consteval auto get-canonical-unit(Unit auto u); // exposition only +
    Returns: The instantiation of canonical-unit for u.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.char.traits.html b/HEAD/api_reference/gen/qty.char.traits.html new file mode 100644 index 00000000..028bae86 --- /dev/null +++ b/HEAD/api_reference/gen/qty.char.traits.html @@ -0,0 +1,12 @@ +[qty.char.traits]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.2 Traits [qty.rep.traits]

    5.5.2.2 Quantity character [qty.char.traits]

    template<typename T> +constexpr bool disable_scalar = false; +template<typename T> +constexpr bool disable_complex = false; +template<typename T> +constexpr bool disable_vector = false; +
    Some quantities are defined as having a numerical value (IEC 60050, 112-01-29) of a specific set (IEC 60050, 102-01-02).
    The representation concepts use these traits +to help determine the sets T represents.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize these templates +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    [Note 1: 
    These templates prevent use of representation types with the library +that satisfy but do not in fact model their corresponding concept.
    — end note]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.chrono.html b/HEAD/api_reference/gen/qty.chrono.html index c522d834..60abc793 100644 --- a/HEAD/api_reference/gen/qty.chrono.html +++ b/HEAD/api_reference/gen/qty.chrono.html @@ -1 +1,78 @@ -[qty.chrono]

    5 Quantities library [qties]

    5.12 std​::​chrono compatibility [qty.chrono]

    \ No newline at end of file +[qty.chrono]

    5 Quantities and units library [quantities]

    5.9 std​::​chrono interoperability [qty.chrono]

    namespace mp_units { + +template<typename Period> +consteval auto time-unit-from-chrono-period() +{ + using namespace si; + + if constexpr (is_same_v<Period, std::chrono::nanoseconds::period>) + return nano<second>; + else if constexpr (is_same_v<Period, std::chrono::microseconds::period>) + return micro<second>; + else if constexpr (is_same_v<Period, std::chrono::milliseconds::period>) + return milli<second>; + else if constexpr (is_same_v<Period, std::chrono::seconds::period>) + return second; + else if constexpr (is_same_v<Period, std::chrono::minutes::period>) + return minute; + else if constexpr (is_same_v<Period, std::chrono::hours::period>) + return hour; + else if constexpr (is_same_v<Period, std::chrono::days::period>) + return day; + else if constexpr (is_same_v<Period, std::chrono::weeks::period>) + return mag<7> * day; + else + return mag_ratio<Period::num, Period::den> * second; +} + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>> { + static constexpr auto reference = time-unit-from-chrono-period<Period>(); + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = false; + using rep = Rep; + using T = std::chrono::duration<Rep, Period>; + + static constexpr rep to_numerical_value(const T& q) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return q.count(); + } + + static constexpr T from_numerical_value(const rep& v) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return T(v); + } +}; + +template<typename Clock> +struct chrono_point_origin_ final : absolute_point_origin<isq::time> { + using clock = Clock; +}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>> { + static constexpr auto reference = time-unit-from-chrono-period<Period>(); + static constexpr auto point_origin = chrono_point_origin<Clock>; + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = false; + using rep = Rep; + using T = std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>; + + static constexpr rep to_numerical_value(const T& tp) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return tp.time_since_epoch().count(); + } + + static constexpr T from_numerical_value(const rep& v) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return T(std::chrono::duration<Rep, Period>(v)); + } +}; + +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.cmp.html b/HEAD/api_reference/gen/qty.cmp.html new file mode 100644 index 00000000..bbeb4b8f --- /dev/null +++ b/HEAD/api_reference/gen/qty.cmp.html @@ -0,0 +1,29 @@ +[qty.cmp]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.12 Comparison [qty.cmp]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let C be +std​::​equality_comparable if @ is ==, and +std​::​three_way_comparable if @ is <=>.
    Effects: Equivalent to: +using ct = std::common_type_t<quantity, quantity<R2, Rep2>>; +const ct ct_lhs(lhs); +const ct ct_rhs(rhs); +return ct_lhs.numerical_value_ref_in(ct::unit) @ ct_rhs.numerical_value_ref_in(ct::unit); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + typename std::common_type_t<quantity, quantity<R2, Rep2>>; +} && C<typename std::common_type_t<quantity, quantity<R2, Rep2>>::rep> +
    template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr bool operator==(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); +
    Let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Returns: lhs.numerical_value_ref_in(unit) @ rhs.
    Remarks: The expression in the requires-clause is equivalent to: +(Q::unit == ::mp_units::one) && C<Rep, Value> +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.common.type.html b/HEAD/api_reference/gen/qty.common.type.html new file mode 100644 index 00000000..626ea43d --- /dev/null +++ b/HEAD/api_reference/gen/qty.common.type.html @@ -0,0 +1,21 @@ +[qty.common.type]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.16 std​::​common_type specializations [qty.common.type]

    template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires requires { + { mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference; + typename std::common_type_t<typename Q1::rep, typename Q2::rep>; + requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>, + mp_units::get_common_quantity_spec(Q1::quantity_spec, + Q2::quantity_spec)>; + } +struct std::common_type<Q1, Q2> { + using type = mp_units::quantity<mp_units::get_common_reference(Q1::reference, Q2::reference), + std::common_type_t<typename Q1::rep, typename Q2::rep>>; +}; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires(Q::unit == mp_units::one) && requires { + typename mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; + } +struct std::common_type<Q, Value> { + using type = mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; +}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.common.unit.html b/HEAD/api_reference/gen/qty.common.unit.html new file mode 100644 index 00000000..0f6df09f --- /dev/null +++ b/HEAD/api_reference/gen/qty.common.unit.html @@ -0,0 +1,40 @@ +[qty.common.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.5 Common [qty.common.unit]

    namespace mp_units { + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit final : decltype(get-common-scaled-unit(U1{}, U2{}, Rest{}...))::base-type +{ + using base-type = common_unit; // exposition only + static constexpr auto common-unit = // exposition only + get-common-scaled-unit(U1{}, U2{}, Rest{}...); +}; + +} +
    common_unit is used by the library +to encapsulate a conversion factor between units (IEC 60050, 112-01-33) +common to the operands of quantity addition.
    [Example 1: 
    The result of 1 * km + 1 * mi +has a common unit +encapsulated by common_unit<mi, km>.
    — end example]
    +A program that instantiates a specialization of common_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    template<Unit U1, Unit U2, Unit... Rest> +consteval Unit auto get-common-scaled-unit(U1, U2, Rest... rest) // exposition only + requires see below; +
    Effects: Equivalent to: +constexpr auto res = [] { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + constexpr auto common_mag = common-magnitude(canonical_lhs.mag, canonical_rhs.mag); + if constexpr (common_mag == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit<common_mag, decltype(auto(canonical_lhs.reference_unit))>{}; +}(); +if constexpr (sizeof...(rest) == 0) + return res; +else + return get-common-scaled-unit(res, rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(U1{}, U2{}) && (sizeof...(Rest) == 0 || requires { + get-common-scaled-unit(get-common-scaled-unit(u1, u2), rest...); + })) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.compat.html b/HEAD/api_reference/gen/qty.compat.html deleted file mode 100644 index ef4214d5..00000000 --- a/HEAD/api_reference/gen/qty.compat.html +++ /dev/null @@ -1 +0,0 @@ -[qty.compat]

    5 Quantities library [qties]

    5.9 Compatibility [qty.compat]

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.concepts.html b/HEAD/api_reference/gen/qty.concepts.html deleted file mode 100644 index fa4cd950..00000000 --- a/HEAD/api_reference/gen/qty.concepts.html +++ /dev/null @@ -1,18 +0,0 @@ -[qty.concepts]

    5 Quantities library [qties]

    5.7 Concepts [qty.concepts]

    export template<typename T> -concept representation = - (is_scalar<T> || is_vector<T> || is_tensor<T>)&&std::regular<T> && scalable<T>; -
    export template<typename T, quantity_character Ch> -concept representation_of = - representation<T> && ((Ch == quantity_character::scalar && is_scalar<T>) || - (Ch == quantity_character::vector && is_vector<T>) || - (Ch == quantity_character::tensor && is_tensor<T>)); -
    template<typename T> -concept named-quantity-spec = - (converts-to-base-subobject-of(^T, ^quantity_spec) && template_of(^T) != ^kind_of_); - -template<typename T> -concept some_quantity_spec = - named-quantity-spec<T> || - detail::IntermediateDerivedQuantitySpec<T> || - template_of(^T) == ^kind_of; -
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.cons.html b/HEAD/api_reference/gen/qty.cons.html new file mode 100644 index 00000000..73b55de3 --- /dev/null +++ b/HEAD/api_reference/gen/qty.cons.html @@ -0,0 +1,27 @@ +[qty.cons]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.5 Constructors and assignment [qty.cons]

    template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> +constexpr quantity(FwdValue&& v, R2); + +template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity(FwdValue&& v); +
    Effects: Initializes numerical-value with std​::​forward<FwdValue>(v).
    template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> +constexpr quantity(FwdValue&& v, R2); +
    Effects: Equivalent to +quantity(quantity<R2{}, Value>{std​::​forward<FwdValue>(v), R2{}}).
    template<QuantityConvertibleTo<quantity> Q> +constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q); +
    Effects: Equivalent to sudo-cast<quantity>(q) ([qty.non.mem.conv]).
    template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> +constexpr explicit(see below) quantity(const Q& q); +
    Effects: Equivalent to: +quantity(::mp_units::quantity{quantity_like_traits<Q>::to_numerical_value(q), + quantity_like_traits<Q>::reference}) +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_import || + !std::convertible_to<typename quantity_like_traits<Q>::rep, Rep> +
    template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity& operator=(FwdValue&& v); +
    Effects: Equivalent to numerical-value = std​::​forward<FwdValue>(v).
    Returns: *this.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.conv.html b/HEAD/api_reference/gen/qty.conv.html new file mode 100644 index 00000000..3d2b9375 --- /dev/null +++ b/HEAD/api_reference/gen/qty.conv.html @@ -0,0 +1,29 @@ +[qty.conv]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.6 Conversions [qty.conv]

    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), Rep>{*this};
    template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> +constexpr QuantityOf<quantity_spec> auto in() const; +
    Effects: Equivalent to: +return quantity<reference, ToRep>{*this};
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), ToRep>{*this}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}>(*this);
    template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in() const; +
    Effects: Equivalent to: +return value_cast<ToRep>(*this);
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}, ToRep>(*this);
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.conv.ops.html b/HEAD/api_reference/gen/qty.conv.ops.html new file mode 100644 index 00000000..68e0c018 --- /dev/null +++ b/HEAD/api_reference/gen/qty.conv.ops.html @@ -0,0 +1,17 @@ +[qty.conv.ops]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.8 Conversion operations [qty.conv.ops]

    template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) +explicit operator V_() const & noexcept; +
    Returns: numerical-value.
    template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> +constexpr explicit(see below) operator Q_() const noexcept(see below); +
    Effects: Equivalent to: +return quantity_like_traits<Q>::from_numerical_value( + numerical_value_in(get_unit(quantity_like_traits<Q>::reference))); +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_export || + !std::convertible_to<Rep, typename quantity_like_traits<Q>::rep> +
    +The exception specification is equivalent to: +noexcept(quantity_like_traits<Q>::from_numerical_value(numerical-value)) && + std::is_nothrow_copy_constructible_v<rep> +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.def.pt.orig.html b/HEAD/api_reference/gen/qty.def.pt.orig.html new file mode 100644 index 00000000..7c9967ea --- /dev/null +++ b/HEAD/api_reference/gen/qty.def.pt.orig.html @@ -0,0 +1,8 @@ +[qty.def.pt.orig]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.2 Default [qty.def.pt.orig]

    template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); +
    Effects: Equivalent to: +if constexpr (requires { get_unit(R{}).point-origin; }) + return get_unit(R{}).point-origin; +else + return zeroth_point_origin<get_quantity_spec(R{})>; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.delta.html b/HEAD/api_reference/gen/qty.delta.html new file mode 100644 index 00000000..8df6b4bd --- /dev/null +++ b/HEAD/api_reference/gen/qty.delta.html @@ -0,0 +1,15 @@ +[qty.delta]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.14 Construction helper delta [qty.delta]

    namespace mp_units { + +template<Reference R> +struct delta_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), R{}};
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.derived.unit.html b/HEAD/api_reference/gen/qty.derived.unit.html new file mode 100644 index 00000000..7b1689e5 --- /dev/null +++ b/HEAD/api_reference/gen/qty.derived.unit.html @@ -0,0 +1,22 @@ +[qty.derived.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.6 Derived [qty.derived.unit]

    namespace mp_units { + +template<typename... Expr> +struct derived-unit-impl : // exposition only + unit-interface, + expr-fractions<struct one, Expr...> { + using base-type = derived-unit-impl; // exposition only +}; + +template<SymbolicConstant... Expr> +struct derived_unit final : derived-unit-impl<Expr...> {}; + +} +
    derived_unit is used by the library +to represent a derived unit (IEC 60050, 112-01-19).
    [Example 1: using namespace si::unit_symbols; +int x = m * m; // error: cannot construct from derived_unit<power<si​::​metre, 2>> +int y = m * s; // error: cannot construct from derived_unit<si​::​metre, si​::​second> +int z = m / s; // error: cannot construct from derived_unit<si​::​metre, per<si​::​second>> + — end example]
    +A program that instantiates a specialization of derived_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.dim.concepts.html b/HEAD/api_reference/gen/qty.dim.concepts.html new file mode 100644 index 00000000..be58ec66 --- /dev/null +++ b/HEAD/api_reference/gen/qty.dim.concepts.html @@ -0,0 +1,10 @@ +[qty.dim.concepts]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.2 Dimension [qty.dim]

    5.4.2.2 Concepts [qty.dim.concepts]

    template<typename T> +concept Dimension = SymbolicConstant<T> && std::derived_from<T, dimension-interface>; + +template<typename T> +concept BaseDimension = // exposition only + Dimension<T> && (is-derived-from-specialization-of<T, base_dimension>()); + +template<typename T, auto D> +concept DimensionOf = Dimension<T> && Dimension<decltype(D)> && (T{} == D); +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.dim.general.html b/HEAD/api_reference/gen/qty.dim.general.html new file mode 100644 index 00000000..651992f2 --- /dev/null +++ b/HEAD/api_reference/gen/qty.dim.general.html @@ -0,0 +1,2 @@ +[qty.dim.general]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.2 Dimension [qty.dim]

    5.4.2.1 General [qty.dim.general]

    Subclause [qty.dim] specifies the components +for defining the dimension of a quantity (IEC 60050, 112-01-11).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.dim.html b/HEAD/api_reference/gen/qty.dim.html new file mode 100644 index 00000000..701e6f64 --- /dev/null +++ b/HEAD/api_reference/gen/qty.dim.html @@ -0,0 +1,75 @@ +[qty.dim]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.2 Dimension [qty.dim]

    5.4.2.1 General [qty.dim.general]

    Subclause [qty.dim] specifies the components +for defining the dimension of a quantity (IEC 60050, 112-01-11).

    5.4.2.2 Concepts [qty.dim.concepts]

    template<typename T> +concept Dimension = SymbolicConstant<T> && std::derived_from<T, dimension-interface>; + +template<typename T> +concept BaseDimension = // exposition only + Dimension<T> && (is-derived-from-specialization-of<T, base_dimension>()); + +template<typename T, auto D> +concept DimensionOf = Dimension<T> && Dimension<decltype(D)> && (T{} == D); +

    5.4.2.3 Types [qty.dim.types]

    namespace mp_units { + +template<symbol_text Symbol> +struct base_dimension : dimension-interface { + static constexpr auto symbol = Symbol; // exposition only +}; + +} +
    base_dimension is used +to define the dimension of a base quantity (IEC 60050, 112-01-08).
    Symbol is its symbolic representation.
    [Example 1: inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length; + — end example]
    namespace mp_units { + +template<typename... Expr> +struct derived-dimension-impl // exposition only + : expr-fractions<struct dimension_one, Expr...> {}; + +template<SymbolicConstant... Expr> +struct derived_dimension final : dimension-interface, derived-dimension-impl<Expr...> {}; + +} +
    derived_dimension is used by the library +to represent the dimension of a derived quantity (IEC 60050, 112-01-10).
    [Example 2: constexpr auto dim_acceleration = isq::speed.dimension / isq::dim_time; +int x = dim_acceleration; // error: cannot construct from + // derived_dimension<isq​::​dim_length, per<power<isq​::​dim_time, 2>>> + — end example]
    +A program that instantiates a specialization of derived_dimension +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +struct dimension_one final : dimension-interface, derived-dimension-impl<> {}; + +} +
    dimension_one represents the dimension of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.2.4 Operations [qty.dim.ops]

    namespace mp_units { + +struct dimension-interface { // exposition only + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator*(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator/(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator*(Lhs, Rhs); +
    Returns: expr-multiply<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator/(Lhs, Rhs); +
    Returns: expr-divide<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval Dimension auto inverse(Dimension auto d); +
    Returns: dimension_one / d.
    template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +
    Returns: expr-pow<Num, Den, derived_dimension, struct dimension_one>(d).
    consteval Dimension auto sqrt(Dimension auto d); +
    Returns: pow<1, 2>(d).
    consteval Dimension auto cbrt(Dimension auto d); +
    Returns: pow<1, 3>(d).

    5.4.2.5 Symbol formatting [qty.dim.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); +
    Effects: Equivalent to: +TBD. +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.dim.ops.html b/HEAD/api_reference/gen/qty.dim.ops.html new file mode 100644 index 00000000..0c9fad18 --- /dev/null +++ b/HEAD/api_reference/gen/qty.dim.ops.html @@ -0,0 +1,27 @@ +[qty.dim.ops]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.2 Dimension [qty.dim]

    5.4.2.4 Operations [qty.dim.ops]

    namespace mp_units { + +struct dimension-interface { // exposition only + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator*(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator/(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator*(Lhs, Rhs); +
    Returns: expr-multiply<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator/(Lhs, Rhs); +
    Returns: expr-divide<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval Dimension auto inverse(Dimension auto d); +
    Returns: dimension_one / d.
    template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +
    Returns: expr-pow<Num, Den, derived_dimension, struct dimension_one>(d).
    consteval Dimension auto sqrt(Dimension auto d); +
    Returns: pow<1, 2>(d).
    consteval Dimension auto cbrt(Dimension auto d); +
    Returns: pow<1, 3>(d).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.dim.sym.fmt.html b/HEAD/api_reference/gen/qty.dim.sym.fmt.html new file mode 100644 index 00000000..fcb26ef1 --- /dev/null +++ b/HEAD/api_reference/gen/qty.dim.sym.fmt.html @@ -0,0 +1,7 @@ +[qty.dim.sym.fmt]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.2 Dimension [qty.dim]

    5.4.2.5 Symbol formatting [qty.dim.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); +
    Effects: Equivalent to: +TBD. +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.dim.types.html b/HEAD/api_reference/gen/qty.dim.types.html new file mode 100644 index 00000000..82748482 --- /dev/null +++ b/HEAD/api_reference/gen/qty.dim.types.html @@ -0,0 +1,33 @@ +[qty.dim.types]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.2 Dimension [qty.dim]

    5.4.2.3 Types [qty.dim.types]

    namespace mp_units { + +template<symbol_text Symbol> +struct base_dimension : dimension-interface { + static constexpr auto symbol = Symbol; // exposition only +}; + +} +
    base_dimension is used +to define the dimension of a base quantity (IEC 60050, 112-01-08).
    Symbol is its symbolic representation.
    [Example 1: inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length; + — end example]
    namespace mp_units { + +template<typename... Expr> +struct derived-dimension-impl // exposition only + : expr-fractions<struct dimension_one, Expr...> {}; + +template<SymbolicConstant... Expr> +struct derived_dimension final : dimension-interface, derived-dimension-impl<Expr...> {}; + +} +
    derived_dimension is used by the library +to represent the dimension of a derived quantity (IEC 60050, 112-01-10).
    [Example 2: constexpr auto dim_acceleration = isq::speed.dimension / isq::dim_time; +int x = dim_acceleration; // error: cannot construct from + // derived_dimension<isq​::​dim_length, per<power<isq​::​dim_time, 2>>> + — end example]
    +A program that instantiates a specialization of derived_dimension +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +struct dimension_one final : dimension-interface, derived-dimension-impl<> {}; + +} +
    dimension_one represents the dimension of a quantity of dimension one (IEC 60050, 112-01-13).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.fp.traits.html b/HEAD/api_reference/gen/qty.fp.traits.html new file mode 100644 index 00000000..29cbe541 --- /dev/null +++ b/HEAD/api_reference/gen/qty.fp.traits.html @@ -0,0 +1,19 @@ +[qty.fp.traits]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.2 Traits [qty.rep.traits]

    5.5.2.1 Floating-point [qty.fp.traits]

    template<typename T> +struct actual-value-type : cond-value-type<T> {}; // see N4971, [readable.traits] + +template<typename T> + requires(!std::is_pointer_v<T> && !std::is_array_v<T>) && + requires { typename std::indirectly_readable_traits<T>::value_type; } +struct actual-value-type<T> : std::indirectly_readable_traits<T> {}; + +template<typename T> +using actual-value-type-t = actual-value-type<T>::value_type; + +template<typename Rep> +constexpr bool treat_as_floating_point = + std::chrono::treat_as_floating_point_v<actual-value-type-t<Rep>>; +
    quantity and quantity_point use treat_as_floating_point +to help determine whether implicit conversions are allowed among them.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize treat_as_floating_point +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.general.html b/HEAD/api_reference/gen/qty.general.html new file mode 100644 index 00000000..69f2e594 --- /dev/null +++ b/HEAD/api_reference/gen/qty.general.html @@ -0,0 +1,3 @@ +[qty.general]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.1 General [qty.general]

    Subclause [qty] describes the class template quantity +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of a vector space (IEC 60050, 102-03-01,102-03-04).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.get.common.base.html b/HEAD/api_reference/gen/qty.get.common.base.html new file mode 100644 index 00000000..4f7270ea --- /dev/null +++ b/HEAD/api_reference/gen/qty.get.common.base.html @@ -0,0 +1,7 @@ +[qty.get.common.base]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.4 Get common base [qty.get.common.base]

    In this subclause and [qty.is.child.of], +let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple +, +where par is parent.
    template<QuantitySpec auto A, QuantitySpec auto B> +consteval auto get-common-base(); // exposition only +
    Let +
    • be the number of elements in h(A),
    • be the number of elements in h(B),
    • s be ,
    • A be a tuple of the last s elements of h(A), and
    • B be a tuple of the last s elements of h(B).
    Effects: Looks for x, the first pair-wise equal element in A and B.
    Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.get.kind.html b/HEAD/api_reference/gen/qty.get.kind.html new file mode 100644 index 00000000..9b1f7aab --- /dev/null +++ b/HEAD/api_reference/gen/qty.get.kind.html @@ -0,0 +1,18 @@ +[qty.get.kind]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.2 Get kind [qty.get.kind]

    template<QuantitySpec Q> +consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only +
    Returns:
    • If QuantityKindSpec<Q> is true, +returns remove-kind(q).
    • Otherwise, if +is-derived-from-specialization-of<Q, quantity_spec>() +is true, and +the specialization of Q​::​quantity_spec has a template argument equal to is_kind, +returns q.
    • Otherwise, if Q​::​parent is a valid expression, +returns get-kind-tree-root(Q​::​parent).
    • Otherwise, if DerivedQuantitySpec<Q> is true, +returns +expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) + +where to-kind is defined as follows: +template<QuantitySpec Q> +using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only +
    • Otherwise, returns q.
    template<QuantitySpec Q> +consteval QuantityKindSpec auto get_kind(Q); +
    Returns: kind_of<get-kind-tree-root(Q{})>.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.helpers.html b/HEAD/api_reference/gen/qty.helpers.html deleted file mode 100644 index f39209f4..00000000 --- a/HEAD/api_reference/gen/qty.helpers.html +++ /dev/null @@ -1,5 +0,0 @@ -[qty.helpers]

    5 Quantities library [qties]

    5.5 Helpers [qty.helpers]

    consteval bool converts-to-base-subobject-of(std::meta type, std::meta template_name); -
    Preconditions: is_type(type) && is_template(template_name) is true.
    Returns: true if -[:type:] has an unambiguous and accessible base -that is a specialization of [:template_name:], and -false otherwise.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.html b/HEAD/api_reference/gen/qty.html new file mode 100644 index 00000000..f52ae159 --- /dev/null +++ b/HEAD/api_reference/gen/qty.html @@ -0,0 +1,708 @@ +[qty]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.1 General [qty.general]

    Subclause [qty] describes the class template quantity +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of a vector space (IEC 60050, 102-03-01,102-03-04).

    5.6.2 Interoperability [qty.like]

    The interfaces specified in this subclause and subclause [qty.pt.like] +are used by quantity and quantity_point +to specify conversions with other types representing quantities.
    [Note 1: 
    [qty.chrono] implements them for std​::​chrono​::​duration and std​::​chrono​::​time_point.
    — end note]
    template<typename T, template<typename> typename Traits> +concept qty-like-impl = requires(const T& qty, const Traits<T>::rep& num) { // exposition only + { Traits<T>::to_numerical_value(qty) } -> std::same_as<typename Traits<T>::rep>; + { Traits<T>::from_numerical_value(num) } -> std::same_as<T>; + requires std::same_as<decltype(Traits<T>::explicit_import), const bool>; + requires std::same_as<decltype(Traits<T>::explicit_export), const bool>; + typename std::bool_constant<Traits<T>::explicit_import>; + typename std::bool_constant<Traits<T>::explicit_export>; +}; + +template<typename T> +concept QuantityLike = !Quantity<T> && qty-like-impl<T, quantity_like_traits> && requires { + typename quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; +}; +
    In the following descriptions, let +
    • Traits be quantity_like_traits or quantity_point_like_traits,
    • Q be a type for which Traits<Q> is specialized,
    • qty be an lvalue of type const Q, and
    • num be an lvalue of type const Traits<Q>​::​rep.
    Q models qty-like-impl<Traits> if and only if: +
    • Traits<Q>​::​to_numerical_value(qty) returns the numerical value (IEC 60050, 112-01-29) of qty.
    • Traits<Q>​::​from_numerical_value(num) returns a Q with numerical value num.
    • If Traits is quantity_point_like_traits, +both numerical values are offset from Traits<Q>​::​point_origin.
    If the following expression is true, the specified conversion will be explicit.
    • Traits<Q>​::​explicit_import for the conversion from Q to this library's type.
    • Traits<Q>​::​explicit_export for the conversion from this library's type to Q.

    5.6.3 Class template quantity [qty.syn]

    namespace mp_units { + +template<typename T> +concept Quantity = (is-derived-from-specialization-of<T, quantity>()); // exposition only + +template<typename Q, auto QS> +concept QuantityOf = // exposition only + Quantity<Q> && QuantitySpecOf<decltype(auto(Q::quantity_spec)), QS>; + +template<Unit UFrom, Unit UTo> +consteval bool integral-conversion-factor(UFrom from, UTo to) // exposition only +{ + return is-integral(get-canonical-unit(from).mag / get-canonical-unit(to).mag); +} + +template<typename T> +concept IsFloatingPoint = treat_as_floating_point<T>; // exposition only + +template<typename FromRep, typename ToRep, auto FromUnit = one, auto ToUnit = one> +concept ValuePreservingTo = // exposition only + Representation<std::remove_cvref_t<FromRep>> && Representation<ToRep> && + Unit<decltype(FromUnit)> && Unit<decltype(ToUnit)> && std::assignable_from<ToRep&, FromRep> && + (IsFloatingPoint<ToRep> || (!IsFloatingPoint<std::remove_cvref_t<FromRep>> && + (integral-conversion-factor(FromUnit, ToUnit)))); + +template<typename QFrom, typename QTo> +concept QuantityConvertibleTo = // exposition only + Quantity<QFrom> && Quantity<QTo> && + QuantitySpecConvertibleTo<QFrom::quantity_spec, QTo::quantity_spec> && + UnitConvertibleTo<QFrom::unit, QTo::unit> && + ValuePreservingTo<typename QFrom::rep, typename QTo::rep, QFrom::unit, QTo::unit> && + requires(QFrom q) { sudo-cast<QTo>(q); }; // see [qty.non.mem.conv] + +template<auto QS, typename Func, typename T, typename U> +concept InvokeResultOf = // exposition only + QuantitySpec<decltype(QS)> && std::regular_invocable<Func, T, U> && + RepresentationOf<std::invoke_result_t<Func, T, U>, QS>; + +template<typename Func, typename Q1, typename Q2, + auto QS = std::invoke_result_t<Func, decltype(auto(Q1::quantity_spec)), + decltype(auto(Q2::quantity_spec))>{}> +concept InvocableQuantities = // exposition only + QuantitySpec<decltype(QS)> && Quantity<Q1> && Quantity<Q2> && + InvokeResultOf<QS, Func, typename Q1::rep, typename Q2::rep>; + +template<auto R1, auto R2> +concept HaveCommonReference = requires { get_common_reference(R1, R2); }; // exposition only + +template<typename Func, Quantity Q1, Quantity Q2> +using common-quantity-for = // exposition only + quantity<get_common_reference(Q1::reference, Q2::reference), + std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>; + +template<typename Func, typename Q1, typename Q2> +concept CommonlyInvocableQuantities = // exposition only + Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> && + std::convertible_to<Q1, common-quantity-for<Func, Q1, Q2>> && + std::convertible_to<Q2, common-quantity-for<Func, Q1, Q2>> && + InvocableQuantities<Func, Q1, Q2, + get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>; + +template<auto R1, auto R2, typename Rep1, typename Rep2> +concept SameValueAs = // exposition only + (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>; + +template<typename T> +using quantity-like-type = // exposition only + quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; + +template<typename T, typename U, typename TT = std::remove_reference_t<T>> +concept Mutable = (!std::is_const_v<TT>) && std::derived_from<TT, U>; // exposition only + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity { +public: + Rep numerical-value; // exposition only + + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + using rep = Rep; + + // [qty.static], static member functions + static constexpr quantity zero() noexcept + requires see below; + static constexpr quantity one() noexcept + requires see below; + static constexpr quantity min() noexcept + requires see below; + static constexpr quantity max() noexcept + requires see below; + + // [qty.cons], constructors and assignment + + quantity() = default; + quantity(const quantity&) = default; + quantity(quantity&&) = default; + ~quantity() = default; + + template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> + constexpr quantity(FwdValue&& v, R2); + + template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> + constexpr quantity(FwdValue&& v, R2); + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity(FwdValue&& v); + + template<QuantityConvertibleTo<quantity> Q> + constexpr explicit(see below) quantity(const Q& q); + + template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> + constexpr explicit(see below) quantity(const Q& q); + + quantity& operator=(const quantity&) = default; + quantity& operator=(quantity&&) = default; + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity& operator=(FwdValue&& v); + + // [qty.conv], conversions + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> + constexpr QuantityOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + // [qty.obs], numerical value observers + + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr rep& numerical_value_ref_in(U) & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr const rep& numerical_value_ref_in(U) const & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + void numerical_value_ref_in(U) const && = delete; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> + constexpr rep numerical_value_in(U) const noexcept; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } + constexpr rep force_numerical_value_in(U) const noexcept; + + // [qty.conv.ops], conversion operations + + template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) + explicit operator V_() const & noexcept; + + template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> + constexpr explicit(see below) operator Q_() const noexcept(see below); + + // [qty.unary.ops], unary operations + + constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; + constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; + + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator++(Q&& q) + requires see below; + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator--(Q&& q) + requires see below; + + constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; + constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; + + // [qty.assign.ops], compound assignment operations + + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); + + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); + + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); + + // [qty.arith.ops], arithmetic operations + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); + + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> + friend constexpr Quantity auto operator/(const Value&, const Q&); + + // [qty.cmp], comparison + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr bool operator==(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); + + // [qty.val.cmp], value comparison + friend constexpr bool is_eq_zero(const quantity& q) requires see below; + friend constexpr bool is_neq_zero(const quantity& q) requires see below; + friend constexpr bool is_lt_zero(const quantity& q) requires see below; + friend constexpr bool is_gt_zero(const quantity& q) requires see below; + friend constexpr bool is_lteq_zero(const quantity& q) requires see below; + friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +}; + +template<Representation Value, Reference R> +quantity(Value, R) -> quantity<R{}, Value>; + +template<Representation Value> +quantity(Value) -> quantity<one, Value>; + +template<QuantityLike Q> +explicit(quantity_like_traits<Q>::explicit_import) quantity(Q) + -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>; + +} +
    quantity<R, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.

    5.6.4 Static member functions [qty.static]

    static constexpr quantity zero() noexcept + requires see below; +static constexpr quantity one() noexcept + requires see below; +static constexpr quantity min() noexcept + requires see below; +static constexpr quantity max() noexcept + requires see below; +
    Let F be one of zero, one, min, and max.
    Returns: {representation_values<rep>​::​F(), R}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { representation_values<rep>::F(); } +

    5.6.5 Constructors and assignment [qty.cons]

    template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> +constexpr quantity(FwdValue&& v, R2); + +template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity(FwdValue&& v); +
    Effects: Initializes numerical-value with std​::​forward<FwdValue>(v).
    template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> +constexpr quantity(FwdValue&& v, R2); +
    Effects: Equivalent to +quantity(quantity<R2{}, Value>{std​::​forward<FwdValue>(v), R2{}}).
    template<QuantityConvertibleTo<quantity> Q> +constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q); +
    Effects: Equivalent to sudo-cast<quantity>(q) ([qty.non.mem.conv]).
    template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> +constexpr explicit(see below) quantity(const Q& q); +
    Effects: Equivalent to: +quantity(::mp_units::quantity{quantity_like_traits<Q>::to_numerical_value(q), + quantity_like_traits<Q>::reference}) +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_import || + !std::convertible_to<typename quantity_like_traits<Q>::rep, Rep> +
    template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity& operator=(FwdValue&& v); +
    Effects: Equivalent to numerical-value = std​::​forward<FwdValue>(v).
    Returns: *this.

    5.6.6 Conversions [qty.conv]

    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), Rep>{*this};
    template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> +constexpr QuantityOf<quantity_spec> auto in() const; +
    Effects: Equivalent to: +return quantity<reference, ToRep>{*this};
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), ToRep>{*this}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}>(*this);
    template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in() const; +
    Effects: Equivalent to: +return value_cast<ToRep>(*this);
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}, ToRep>(*this);

    5.6.7 Numerical value observers [qty.obs]

    template<Unit U> + requires(equivalent(U{}, unit)) +constexpr rep& numerical_value_ref_in(U) & noexcept; +template<Unit U> + requires(equivalent(U{}, unit)) +constexpr const rep& numerical_value_ref_in(U) const & noexcept; +
    Returns: numerical-value.
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> +constexpr rep numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).in(U{}).numerical-value;
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } +constexpr rep force_numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).force_in(U{}).numerical-value;

    5.6.8 Conversion operations [qty.conv.ops]

    template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) +explicit operator V_() const & noexcept; +
    Returns: numerical-value.
    template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> +constexpr explicit(see below) operator Q_() const noexcept(see below); +
    Effects: Equivalent to: +return quantity_like_traits<Q>::from_numerical_value( + numerical_value_in(get_unit(quantity_like_traits<Q>::reference))); +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_export || + !std::convertible_to<Rep, typename quantity_like_traits<Q>::rep> +
    +The exception specification is equivalent to: +noexcept(quantity_like_traits<Q>::from_numerical_value(numerical-value)) && + std::is_nothrow_copy_constructible_v<rep> +

    5.6.9 Unary operations [qty.unary.ops]

    In the following descriptions, +let @ be the operator.
    constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; +constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{@numerical-value, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(const rep v) { + { @v } -> std::common_with<rep>; +} +
    template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator++(Q&& q) + requires see below; +template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator--(Q&& q) + requires see below; +
    Effects: Equivalent to +@q.numerical-value.
    Returns: std​::​forward<Q>(q).
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { @v } -> std::same_as<rep&>; +} +
    constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; +constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{numerical-value@, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { v@ } -> std::common_with<rep>; +} +

    5.6.10 Compound assignment operations [qty.assign.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is %=, then is_neq_zero(rhs) is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.in(lhs.unit).numerical-value.
    Returns: std​::​forward<Q>(lhs).
    Remarks: Let C be +
    • (!treat_as_floating_point<rep>) if @ is %=, and
    • true otherwise.
    +The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && C && +requires(rep& a, const Rep2 b) { + { a @ b } -> std::same_as<rep&>; +} +
    Recommended practice: If equivalent(unit, get_unit(rhs.reference)) is true, +then the expression rhs.in(lhs.unit) is replaced with rhs.
    template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); +template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); +
    Preconditions: If @ is /=, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.
    Returns: std​::​forward<Q>(lhs).
    Remarks: The expression in the requires-clause is equivalent to: +(!Quantity<Value>) && requires(rep& a, const Value b) { + { a @ b } -> std::same_as<rep&>; +} +
    template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); +template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); +
    Effects: Equivalent to: +return std​::​forward<Q>(lhs) @ rhs.numerical-value;
    Remarks: The expression in the requires-clause is equivalent to: +(Q2::unit == ::mp_units::one) && ValuePreservingTo<typename Q2::rep, Rep> && +requires(rep& a, const Q2::rep b) { + { a @ b } -> std::same_as<rep&>; +} +

    5.6.11 Arithmetic operations [qty.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let F be the first argument to CommonlyInvocableQuantities.
    Preconditions: If @ is %, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +using ret = common-quantity-for<F, quantity, quantity<R2, Rep2>>; +const ret ret_lhs(lhs); +const ret ret_rhs(rhs); +return ::mp_units::quantity{ + ret_lhs.numerical_value_ref_in(ret::unit) @ ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; +
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); +
    Effects: Equivalent to: +return lhs @ ​::​mp_units​::​quantity{rhs};
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{lhs} @ rhs;
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{ + lhs.numerical_value_ref_in(unit) @ rhs.numerical_value_ref_in(rhs.unit), R @ R2}; +
    template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); +
    Preconditions: If @ is /, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs.numerical_value_ref_in(unit) @ rhs, R}; +
    template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); +template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> +friend constexpr Quantity auto operator/(const Value& lhs, const Q& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs @ rhs.numerical_value_ref_in(unit), ::mp_units::one @ R}; +

    5.6.12 Comparison [qty.cmp]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let C be +std​::​equality_comparable if @ is ==, and +std​::​three_way_comparable if @ is <=>.
    Effects: Equivalent to: +using ct = std::common_type_t<quantity, quantity<R2, Rep2>>; +const ct ct_lhs(lhs); +const ct ct_rhs(rhs); +return ct_lhs.numerical_value_ref_in(ct::unit) @ ct_rhs.numerical_value_ref_in(ct::unit); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + typename std::common_type_t<quantity, quantity<R2, Rep2>>; +} && C<typename std::common_type_t<quantity, quantity<R2, Rep2>>::rep> +
    template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr bool operator==(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); +
    Let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Returns: lhs.numerical_value_ref_in(unit) @ rhs.
    Remarks: The expression in the requires-clause is equivalent to: +(Q::unit == ::mp_units::one) && C<Rep, Value> +

    5.6.13 Value comparison [qty.val.cmp]

    friend constexpr bool is_eq_zero(const quantity& q) requires see below; +friend constexpr bool is_neq_zero(const quantity& q) requires see below; +friend constexpr bool is_lt_zero(const quantity& q) requires see below; +friend constexpr bool is_gt_zero(const quantity& q) requires see below; +friend constexpr bool is_lteq_zero(const quantity& q) requires see below; +friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +
    Let is_F_zero be the function name.
    Returns:
    Remarks: Let C be +std​::​equality_comparable_with if F is eq or neq, and +std​::​three_way_comparable_with otherwise.
    The expression in the requires-clause is equivalent to: +requires { + { T::zero() } -> C<quantity>; +} +

    5.6.14 Construction helper delta [qty.delta]

    namespace mp_units { + +template<Reference R> +struct delta_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), R{}};

    5.6.15 Non-member conversions [qty.non.mem.conv]

    template<Quantity To, typename FwdFrom, Quantity From = std::remove_cvref_t<FwdFrom>> + requires see below +constexpr To sudo-cast(FwdFrom&& q); // exposition only +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToU)) +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), typename Q::rep>>( + std::forward<FwdQ>(q)); +
    template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires RepresentationOf<ToRep, Q::quantity_spec> && + std::constructible_from<ToRep, typename Q::rep> +constexpr quantity<Q::reference, ToRep> value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<Q::reference, ToRep>>(std::forward<FwdQ>(q)); +
    template<Unit auto ToU, Representation ToRep, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +template<Representation ToRep, Unit auto ToU, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), ToRep>>( + std::forward<FwdQ>(q)); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec> && +std::constructible_from<ToRep, typename Q::rep> +
    template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToQ::unit)) && (ToQ::quantity_spec == Q::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename Q::rep> +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: return sudo-cast<ToQ>(std​::​forward<FwdQ>(q));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    [Example 1: auto length = isq::length(42 * m); +auto distance = quantity_cast<isq::distance>(length); + — end example]
    template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecCastableTo<Q::quantity_spec, ToQS> +constexpr Quantity auto quantity_cast(FwdQ&& q); +
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, make-reference(ToQS, Q::unit)}; +

    5.6.16 std​::​common_type specializations [qty.common.type]

    template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires requires { + { mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference; + typename std::common_type_t<typename Q1::rep, typename Q2::rep>; + requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>, + mp_units::get_common_quantity_spec(Q1::quantity_spec, + Q2::quantity_spec)>; + } +struct std::common_type<Q1, Q2> { + using type = mp_units::quantity<mp_units::get_common_reference(Q1::reference, Q2::reference), + std::common_type_t<typename Q1::rep, typename Q2::rep>>; +}; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires(Q::unit == mp_units::one) && requires { + typename mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; + } +struct std::common_type<Q, Value> { + using type = mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; +}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.imag.cpo.html b/HEAD/api_reference/gen/qty.imag.cpo.html new file mode 100644 index 00000000..fb81b9a1 --- /dev/null +++ b/HEAD/api_reference/gen/qty.imag.cpo.html @@ -0,0 +1,8 @@ +[qty.imag.cpo]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    The name mp_units​::​imag denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​imag(E) is ill-formed.
    • If auto(t.imag()) is a valid expression whose type models Scalar, +mp_units​::​imag(E) is expression-equivalent to auto(t.imag()).
    • Otherwise, if T is a class or enumeration type and +auto(imag(t)) is a valid expression whose type models Scalar +where the meaning of imag is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​imag(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​imag(E) is ill-formed.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.is.child.of.html b/HEAD/api_reference/gen/qty.is.child.of.html new file mode 100644 index 00000000..a5ebf414 --- /dev/null +++ b/HEAD/api_reference/gen/qty.is.child.of.html @@ -0,0 +1,4 @@ +[qty.is.child.of]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.5 Is child of [qty.is.child.of]

    template<QuantitySpec Child, QuantitySpec Parent> +consteval bool is-child-of(Child ch, Parent p); // exposition only +
    Returns: If h(p) has more elements than h(ch), returns false.
    Otherwise, let C be a tuple of the last s elements of h(ch), +where s is the number of elements in h(p).
    Returns == p.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.like.html b/HEAD/api_reference/gen/qty.like.html new file mode 100644 index 00000000..6cf0d332 --- /dev/null +++ b/HEAD/api_reference/gen/qty.like.html @@ -0,0 +1,20 @@ +[qty.like]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.2 Interoperability [qty.like]

    The interfaces specified in this subclause and subclause [qty.pt.like] +are used by quantity and quantity_point +to specify conversions with other types representing quantities.
    [Note 1: 
    [qty.chrono] implements them for std​::​chrono​::​duration and std​::​chrono​::​time_point.
    — end note]
    template<typename T, template<typename> typename Traits> +concept qty-like-impl = requires(const T& qty, const Traits<T>::rep& num) { // exposition only + { Traits<T>::to_numerical_value(qty) } -> std::same_as<typename Traits<T>::rep>; + { Traits<T>::from_numerical_value(num) } -> std::same_as<T>; + requires std::same_as<decltype(Traits<T>::explicit_import), const bool>; + requires std::same_as<decltype(Traits<T>::explicit_export), const bool>; + typename std::bool_constant<Traits<T>::explicit_import>; + typename std::bool_constant<Traits<T>::explicit_export>; +}; + +template<typename T> +concept QuantityLike = !Quantity<T> && qty-like-impl<T, quantity_like_traits> && requires { + typename quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; +}; +
    In the following descriptions, let +
    • Traits be quantity_like_traits or quantity_point_like_traits,
    • Q be a type for which Traits<Q> is specialized,
    • qty be an lvalue of type const Q, and
    • num be an lvalue of type const Traits<Q>​::​rep.
    Q models qty-like-impl<Traits> if and only if: +
    • Traits<Q>​::​to_numerical_value(qty) returns the numerical value (IEC 60050, 112-01-29) of qty.
    • Traits<Q>​::​from_numerical_value(num) returns a Q with numerical value num.
    • If Traits is quantity_point_like_traits, +both numerical values are offset from Traits<Q>​::​point_origin.
    If the following expression is true, the specified conversion will be explicit.
    • Traits<Q>​::​explicit_import for the conversion from Q to this library's type.
    • Traits<Q>​::​explicit_export for the conversion from this library's type to Q.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.mag.cpo.html b/HEAD/api_reference/gen/qty.mag.cpo.html new file mode 100644 index 00000000..3db48ae1 --- /dev/null +++ b/HEAD/api_reference/gen/qty.mag.cpo.html @@ -0,0 +1,12 @@ +[qty.mag.cpo]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    The name mp_units​::​magnitude denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​magnitude(E) is ill-formed.
    • If auto(t.magnitude()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(E) is expression-equivalent to auto(t.magnitude()).
    • Otherwise, if T is a class or enumeration type and +auto(magnitude(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, if auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(​E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​magnitude(E) is ill-formed.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.modulus.cpo.html b/HEAD/api_reference/gen/qty.modulus.cpo.html new file mode 100644 index 00000000..4316fe03 --- /dev/null +++ b/HEAD/api_reference/gen/qty.modulus.cpo.html @@ -0,0 +1,12 @@ +[qty.modulus.cpo]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    The name mp_units​::​modulus denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​modulus(E) is ill-formed.
    • If auto(t.modulus()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.modulus()).
    • Otherwise, if T is a class or enumeration type and +auto(modulus(t)) is a valid expression whose type models Scalar +where the meaning of modulus is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • If auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of abs is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​modulus(E) is ill-formed.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.named.unit.html b/HEAD/api_reference/gen/qty.named.unit.html new file mode 100644 index 00000000..a8574391 --- /dev/null +++ b/HEAD/api_reference/gen/qty.named.unit.html @@ -0,0 +1,81 @@ +[qty.named.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.3 Named [qty.named.unit]

    namespace mp_units { + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS, PO> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol> + requires(!Symbol.empty()) +struct named_unit<Symbol> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U> + requires(!Symbol.empty()) +struct named_unit<Symbol, U> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires(!Symbol.empty()) +struct named_unit<Symbol, U, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +} +
    A named unit is a type that models PrefixableUnit.
    A specialization of named_unit is used as a base type when defining a named unit.
    In the following descriptions, let U be a named unit defined with an alluded signature.
    The identifier of U represents +its unit name (IEC 60050, 112-01-15) +or special unit name (IEC 60050, 112-01-16).
    Symbol is its unit symbol (IEC 60050, 112-01-17).
    The possible arguments to named_unit are +
    • ,
    • ,
    • , and
    • .
    The first signature defines the unit of a base quantity +without a unit prefix (IEC 60050, 112-01-26).
    The second signature defines a unit +that can be reused by several base quantities.
    The third and fourth signatures with a unit expression argument E +define U as implicitly convertible from E.
    The first and fourth signatures with a kind of quantity (IEC 60050, 112-01-04) Q +also restrict U to Q.
    A point origin argument specifies the default point origin of U ([qty.pt.syn]).
    [Example 1: // 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; // . + +// The fourth signature also further restricts the kind of quantity. +inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { +} hertz; // Hz can't measure becquerel, activity, + // or any other quantity with dimension + // that isn't a kind of frequency. + — end example]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.non.mem.conv.html b/HEAD/api_reference/gen/qty.non.mem.conv.html new file mode 100644 index 00000000..b03a29b4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.non.mem.conv.html @@ -0,0 +1,41 @@ +[qty.non.mem.conv]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.15 Non-member conversions [qty.non.mem.conv]

    template<Quantity To, typename FwdFrom, Quantity From = std::remove_cvref_t<FwdFrom>> + requires see below +constexpr To sudo-cast(FwdFrom&& q); // exposition only +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToU)) +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), typename Q::rep>>( + std::forward<FwdQ>(q)); +
    template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires RepresentationOf<ToRep, Q::quantity_spec> && + std::constructible_from<ToRep, typename Q::rep> +constexpr quantity<Q::reference, ToRep> value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<Q::reference, ToRep>>(std::forward<FwdQ>(q)); +
    template<Unit auto ToU, Representation ToRep, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +template<Representation ToRep, Unit auto ToU, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), ToRep>>( + std::forward<FwdQ>(q)); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec> && +std::constructible_from<ToRep, typename Q::rep> +
    template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToQ::unit)) && (ToQ::quantity_spec == Q::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename Q::rep> +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: return sudo-cast<ToQ>(std​::​forward<FwdQ>(q));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    [Example 1: auto length = isq::length(42 * m); +auto distance = quantity_cast<isq::distance>(length); + — end example]
    template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecCastableTo<Q::quantity_spec, ToQS> +constexpr Quantity auto quantity_cast(FwdQ&& q); +
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, make-reference(ToQS, Q::unit)}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.obs.html b/HEAD/api_reference/gen/qty.obs.html new file mode 100644 index 00000000..8d1e29d4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.obs.html @@ -0,0 +1,15 @@ +[qty.obs]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.7 Numerical value observers [qty.obs]

    template<Unit U> + requires(equivalent(U{}, unit)) +constexpr rep& numerical_value_ref_in(U) & noexcept; +template<Unit U> + requires(equivalent(U{}, unit)) +constexpr const rep& numerical_value_ref_in(U) const & noexcept; +
    Returns: numerical-value.
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> +constexpr rep numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).in(U{}).numerical-value;
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } +constexpr rep force_numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).force_in(U{}).numerical-value;
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.one.html b/HEAD/api_reference/gen/qty.one.html deleted file mode 100644 index 0ba252eb..00000000 --- a/HEAD/api_reference/gen/qty.one.html +++ /dev/null @@ -1 +0,0 @@ -[qty.one]

    5 Quantities library [qties]

    5.10 Dimension one [qty.one]

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.point.html b/HEAD/api_reference/gen/qty.point.html new file mode 100644 index 00000000..cc7ca388 --- /dev/null +++ b/HEAD/api_reference/gen/qty.point.html @@ -0,0 +1,15 @@ +[qty.point]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.14 Construction helper point [qty.point]

    namespace mp_units { + +template<Reference R> +struct point_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity_point{quantity{std​::​forward<FwdRep>(lhs), R{}}};
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.point.type.html b/HEAD/api_reference/gen/qty.point.type.html deleted file mode 100644 index f2d78246..00000000 --- a/HEAD/api_reference/gen/qty.point.type.html +++ /dev/null @@ -1,11 +0,0 @@ -[qty.point.type]

    5 Quantities library [qties]

    5.8 Types [qty.types]

    5.8.3 Class template quantity_point [qty.point.type]

    namespace mp_units { - -export template<unspecified> -class quantity_point { unspecified }; - -} -
    A quantity point type is a specialization of quantity_point.
    Let Q be a quantity point type.
    Q​::​point_origin represents -the origin point of a position vector (IEC 60050, 102-03-15).
    • If Rep is a scalar, -Q represents the scalar quantity (IEC 60050, 102-02-19) -of a position vector.
    • If Rep is a vector, -Q represents a position vector.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.prefixed.unit.html b/HEAD/api_reference/gen/qty.prefixed.unit.html new file mode 100644 index 00000000..060d1306 --- /dev/null +++ b/HEAD/api_reference/gen/qty.prefixed.unit.html @@ -0,0 +1,18 @@ +[qty.prefixed.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.4 Prefixed [qty.prefixed.unit]

    namespace mp_units { + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires(!Symbol.empty()) +struct prefixed_unit : decltype(M * U)::base-type { + using base-type = prefixed_unit; // exposition only + static constexpr auto symbol = Symbol + U.symbol; // exposition only +}; + +} +
    prefixed_unit<Symbol, M, U> represents the unit U with a unit prefix (IEC 60050, 112-01-26).
    Symbol is the symbol of the unit prefix.
    M is the factor of the unit prefix.
    A specialization of prefixed_unit is used as a base type when defining a unit prefix.
    [Example 1: template<PrefixableUnit auto U> +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + +template<PrefixableUnit auto U> +constexpr kilo_<U> kilo; + +inline constexpr auto kilogram = kilo<si::gram>; + — end example]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.arith.ops.html b/HEAD/api_reference/gen/qty.pt.arith.ops.html new file mode 100644 index 00000000..3e253392 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.arith.ops.html @@ -0,0 +1,51 @@ +[qty.pt.arith.ops]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.12 Arithmetic operations [qty.pt.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +
    Effects: Equivalent to: +if constexpr (is-specialization-of<PO, zeroth_point_origin>()) + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q}; +else + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q, PO}; +
    Remarks: The expression in the requires-clause is equivalent to: +ReferenceOf<decltype(R2), PO.quantity-spec> && requires { + qp.quantity_ref_from(PO) @ q; +} +
    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> +friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; +
    Effects: Equivalent to: +return lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin) + + (lhs.point_origin - rhs.point_origin); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin); } +
    Recommended practice: The subtraction of two equal origins is not evaluated.
    template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(const QP& qp, PO2 po); +template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(PO2 po, const QP& qp); +
    Effects: For the first signature, +equivalent to: +if constexpr (point_origin == po) + return qp.quantity_ref_from(point_origin); +else if constexpr (is-derived-from-specialization-of<PO2, + ::mp_units::absolute_point_origin>()) { + return qp.quantity_ref_from(point_origin) + (qp.point_origin - qp.absolute_point_origin); +} else { + return qp.quantity_ref_from(point_origin) - + po.quantity-point.quantity_ref_from(po.quantity-point.point_origin) + + (qp.point_origin - po.quantity-point.point_origin); +} +
    +For the second signature, +equivalent to: return -(qp - po);
    Remarks: The expression in the requires-clause is equivalent to: +QuantityPointOf<quantity_point, PO2{}> && + ReferenceOf<decltype(auto(reference)), PO2::quantity-spec> +
    Recommended practice: The subtraction of two equal origins is not evaluated.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.assign.ops.html b/HEAD/api_reference/gen/qty.pt.assign.ops.html new file mode 100644 index 00000000..79615b9f --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.assign.ops.html @@ -0,0 +1,11 @@ +[qty.pt.assign.ops]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.11 Compound assignment operations [qty.pt.assign.ops]

    template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); +template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); +
    Let @ be the operator.
    Effects: Equivalent to +qp.quantity-from-origin @ q.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity_type> && + requires { qp.quantity-from-origin @ q; } +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.cmp.html b/HEAD/api_reference/gen/qty.pt.cmp.html new file mode 100644 index 00000000..984d792d --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.cmp.html @@ -0,0 +1,16 @@ +[qty.pt.cmp]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.13 Comparison [qty.pt.cmp]

    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr bool operator==(const QP& lhs, const QP2& rhs); +template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +
    Let @ be the operator, and +let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Effects: Equivalent to: +return lhs - lhs.absolute_point_origin @ rhs - rhs.absolute_point_origin; +
    Remarks: The expression in the requires-clause is equivalent to: +C<quantity_type, typename QP2::quantity_type> +
    Recommended practice: If the origins are equal, instead evaluate +lhs.quantity_ref_from(point_origin) @ rhs.quantity_ref_from(QP2::point_origin) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.cons.html b/HEAD/api_reference/gen/qty.pt.cons.html new file mode 100644 index 00000000..1d0985f7 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.cons.html @@ -0,0 +1,34 @@ +[qty.pt.cons]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.6 Constructors [qty.pt.cons]

    template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) +constexpr explicit quantity_point(FwdQ&& q); + +template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> +constexpr quantity_point(FwdQ&& q, decltype(PO)); +
    Effects: Initializes quantity-from-origin with std​::​forward<FwdQ>(q).
    template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> +constexpr quantity_point(FwdQ&& q, PO2); +
    Effects: Equivalent to: +quantity_point(quantity_point<Q::reference, PO2{}, typename Q::rep>{std::forward<FwdQ>(q), + PO2{}}) +
    template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> +constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); +
    Effects: If point_origin == QP​::​point_origin is true, +initializes quantity-from-origin with qp.quantity_ref_from(point_origin).
    Otherwise, initializes quantity-from-origin with qp - point_origin.
    template<QuantityPointLike QP> + requires see below +constexpr explicit(see below) quantity_point(const QP& qp); +
    Let Traits be quantity_point_like_traits<QP>.
    Effects: Initializes quantity-from-origin with +Traits::to_numerical_value(qp), get_unit(Traits::reference) +
    Remarks: The expression in the requires-clause is equivalent to: +(Traits::point_origin == point_origin) && + std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +
    +The expression inside explicit is equivalent to: +Traits::explicit_import || + !std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.conv.html b/HEAD/api_reference/gen/qty.pt.conv.html new file mode 100644 index 00000000..e5703fd4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.conv.html @@ -0,0 +1,38 @@ +[qty.pt.conv]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.7 Conversions [qty.pt.conv]

    template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> +constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; +
    Effects: Equivalent to: +if constexpr (std::is_same_v<NewPO, decltype(point_origin)>) + return *this; +else + return ::mp_units::quantity_point{*this - new_origin, new_origin}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; +
    Let converted-quantity-expr be an expression denoting +the function call to the corresponding member of quantity_ref_from(point_origin).
    Effects: Equivalent to: +return ::mp_units::quantity_point{converted-quantity-expr, point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { converted-quantity-expr; } +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.conv.ops.html b/HEAD/api_reference/gen/qty.pt.conv.ops.html new file mode 100644 index 00000000..6bf4710f --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.conv.ops.html @@ -0,0 +1,21 @@ +[qty.pt.conv.ops]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.9 Conversion operations [qty.pt.conv.ops]

    template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() const & noexcept(see below); +template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() && noexcept(see below); +
    Let Traits be quantity_point_like_traits<QP>.
    Let result-expr be +Traits::from_numerical_value(std::move(quantity-from-origin).numerical-value) +
    Returns: result-expr.
    Remarks: The expression in the requires-clause is equivalent to: +(point_origin == Traits::point_origin) && + std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +The expression inside explicit is equivalent to: +Traits::explicit_export || + !std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +Let T be +std​::​is_nothrow_copy_constructible_v for the first signature, and +std​::​is_nothrow_move_constructible_v for the second signature.
    The exception specification is equivalent to: +noexcept(result-expr) && T<rep> +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.general.html b/HEAD/api_reference/gen/qty.pt.general.html new file mode 100644 index 00000000..b56e5a13 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.general.html @@ -0,0 +1,3 @@ +[qty.pt.general]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.1 General [qty.pt.general]

    Subclause [qty.pt] describes the class template quantity_point +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of an affine space (IEC 60050, 102-03-02,102-04-01).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.html b/HEAD/api_reference/gen/qty.pt.html new file mode 100644 index 00000000..9483fa07 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.html @@ -0,0 +1,621 @@ +[qty.pt]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.1 General [qty.pt.general]

    Subclause [qty.pt] describes the class template quantity_point +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of an affine space (IEC 60050, 102-03-02,102-04-01).

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.1 General [qty.pt.orig.general]

    This subclause specifies the components +for defining the origin of an affine space.
    An origin is a point from which measurements (IEC 60050, 112-04-01) take place.

    5.7.2.2 Concepts [qty.pt.orig.concepts]

    template<typename T> +concept PointOrigin = SymbolicConstant<T> && std::derived_from<T, point-origin-interface>; + +template<typename T, auto QS> +concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<decltype(QS), T::quantity-spec>; + +template<typename T, auto V> +concept SameAbsolutePointOriginAs = // exposition only + PointOrigin<T> && PointOrigin<decltype(V)> && same-absolute-point-origins(T{}, V); +

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.1 Absolute [qty.abs.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct absolute_point_origin : point-origin-interface { + static constexpr QuantitySpec auto quantity-spec = QS; // exposition only +}; + +} +
    An absolute origin is an origin +chosen by convention and not defined in terms of another origin.
    A specialization of absolute_point_origin is used as a base type when defining an absolute origin.
    QS is the quantity the origin represents.

    5.7.2.3.2 Relative [qty.rel.pt.orig]

    namespace mp_units { + +template<QuantityPoint auto QP> +struct relative_point_origin : point-origin-interface { + static constexpr QuantityPoint auto quantity-point = QP; // exposition only + static constexpr QuantitySpec auto quantity-spec = see below; // exposition only + static constexpr PointOrigin auto absolute-point-origin = // exposition only + QP.absolute_point_origin; +}; + +} +
    A relative origin is an origin +of a subspace (IEC 60050, 102-03-03).
    A specialization of relative_point_origin is used as a base type when defining a relative origin O.
    O is offset from QP.absolute_point_origin by QP.quantity_from_zero().
    The member quantity-spec is equal to +QP.point_origin.quantity-spec if +QuantityKindSpec<decltype(auto(QP.quantity-spec))> + +is satisfied, and +to QP.quantity-spec otherwise.

    5.7.2.3.3 Zeroth [qty.zeroth.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct zeroth_point_origin_ final : absolute_point_origin<QS> {}; + +} +
    zeroth_point_origin_<QS> represents an origin +chosen by convention as the value 0 of the quantity QS.

    5.7.2.4 Operations [qty.pt.orig.ops]

    namespace mp_units { + +struct point-origin-interface { + template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); + template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); + + template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> + friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; + + template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below + friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); + + template<PointOrigin PO1, PointOrigin PO2> + friend consteval bool operator==(PO1 po1, PO2 po2); +}; + +} +
    template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); +template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); +
    Effects: Equivalent to: +return quantity_point{std​::​forward<FwdQ>(q), PO{}};
    template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> +friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; +
    Effects: Equivalent to: +return po + -q;
    template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below +friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>()) { + return po1 - po2.quantity-point; +} else if constexpr (is-derived-from-specialization-of<PO2, absolute_point_origin>()) { + return po1.quantity-point - po2; +} else { + return po1.quantity-point - po2.quantity-point; +} +
    Remarks: The expression in the requires-clause is equivalent to: +QuantitySpecOf<decltype(auto(PO1::quantity-spec)), PO2::quantity-spec> && + (is-derived-from-specialization-of<PO1, relative_point_origin>() || + is-derived-from-specialization-of<PO2, relative_point_origin>()) +
    template<PointOrigin PO1, PointOrigin PO2> +friend consteval bool operator==(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return std::is_same_v<PO1, PO2> || + (is-specialization-of<PO1, zeroth_point_origin>() && + is-specialization-of<PO2, zeroth_point_origin>() && + interconvertible(po1.quantity-spec, po2.quantity-spec)); +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return PO1::quantity-point == PO2::quantity-point; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO1::quantity-point.quantity_from_zero()); +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO2::quantity-point.quantity_from_zero()); +

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.1 Same absolute [qty.same.abs.pt.origs]

    template<PointOrigin PO1, PointOrigin PO2> +consteval bool same-absolute-point-origins(PO1 po1, PO2 po2); // exposition only +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return po1 == po2; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1.absolute-point-origin == po2.absolute-point-origin; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return po1.absolute-point-origin == po2; +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1 == po2.absolute-point-origin; +else + return false; +

    5.7.2.5.2 Default [qty.def.pt.orig]

    template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); +
    Effects: Equivalent to: +if constexpr (requires { get_unit(R{}).point-origin; }) + return get_unit(R{}).point-origin; +else + return zeroth_point_origin<get_quantity_spec(R{})>; +

    5.7.3 Interoperability [qty.pt.like]

    template<typename T> +concept QuantityPointLike = + !QuantityPoint<T> && + qty-like-impl<T, quantity_point_like_traits> && // see [qty.like] + requires { + typename quantity_point<quantity_point_like_traits<T>::reference, + quantity_point_like_traits<T>::point_origin, + typename quantity_point_like_traits<T>::rep>; + }; +

    5.7.4 Class template quantity_point [qty.pt.syn]

    namespace mp_units { + +template<typename T> +concept QuantityPoint = (is-derived-from-specialization-of<T, quantity_point>()); + +template<typename QP, auto V> +concept QuantityPointOf = + QuantityPoint<QP> && (QuantitySpecOf<decltype(auto(QP::quantity_spec)), V> || + SameAbsolutePointOriginAs<decltype(auto(QP::absolute_point_origin)), V>); + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point { +public: + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + static constexpr PointOrigin auto absolute_point_origin = see below; + static constexpr PointOrigin auto point_origin = PO; + using rep = Rep; + using quantity_type = quantity<reference, Rep>; + + quantity_type quantity-from-origin; // exposition only + + // [qty.pt.static], static member functions + static constexpr quantity_point min() noexcept + requires see below; + static constexpr quantity_point max() noexcept + requires see below; + + // [qty.pt.cons], constructors and assignment + + quantity_point() = default; + quantity_point(const quantity_point&) = default; + quantity_point(quantity_point&&) = default; + ~quantity_point() = default; + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) + constexpr explicit quantity_point(FwdQ&& q); + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> + constexpr quantity_point(FwdQ&& q, decltype(PO)); + + template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> + constexpr quantity_point(FwdQ&& q, PO2); + + template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> + constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); + + template<QuantityPointLike QP> + requires see below + constexpr explicit(see below) quantity_point(const QP& qp); + + quantity_point& operator=(const quantity_point&) = default; + quantity_point& operator=(quantity_point&&) = default; + + // [qty.pt.conv], conversions + + template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> + constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + // [qty.pt.obs], quantity value observers + + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr quantity_type& quantity_ref_from(PO2) & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + void quantity_ref_from(PO2) const && = delete; + + template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } + constexpr Quantity auto quantity_from(PO2) const; + + template<QuantityPointOf<absolute_point_origin> QP> + constexpr Quantity auto quantity_from(const QP&) const; + + constexpr Quantity auto quantity_from_zero() const; + + // [qty.pt.conv.ops], conversion operations + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() const & noexcept(see below); + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() && noexcept(see below); + + // [qty.pt.unary.ops], unary operations + + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; + + constexpr quantity_point operator++(int) + requires see below; + constexpr quantity_point operator--(int) + requires see below; + + // [qty.pt.assign.ops], compound assignment operations + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); + + // [qty.pt.arith.ops], arithmetic operations + + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; + + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(const QP& qp, PO2 po); + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(PO2 po, const QP& qp); + + // [qty.pt.cmp], comparison + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr bool operator==(const QP& lhs, const QP2& rhs); + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +}; + +template<Quantity Q> +explicit quantity_point(Q q) + -> quantity_point<Q::reference, default_point_origin(Q::reference), typename Q::rep>; + +template<Quantity Q, PointOriginFor<Q::quantity_spec> PO> +quantity_point(Q, PO) -> quantity_point<Q::reference, PO{}, typename Q::rep>; + +template<QuantityPointLike QP, typename Traits = quantity_point_like_traits<QP>> +explicit(quantity_point_like_traits<QP>::explicit_import) quantity_point(QP) + -> quantity_point<Traits::reference, Traits::point_origin, typename Traits::rep>; + +} +
    quantity_point<R, PO, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.
    The member absolute_point_origin is equal to PO if +is-derived-from-specialization-of<decltype(PO), absolute_point_origin>() + +is true, and +to PO.quantity-point.absolute_point_origin otherwise.

    5.7.5 Static member functions [qty.pt.static]

    static constexpr quantity_point min() noexcept + requires see below; +static constexpr quantity_point max() noexcept + requires see below; +
    Let F be one of min and max.
    Returns: {quantity_type​::​F(), PO}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity_type::F(); } +

    5.7.6 Constructors [qty.pt.cons]

    template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) +constexpr explicit quantity_point(FwdQ&& q); + +template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> +constexpr quantity_point(FwdQ&& q, decltype(PO)); +
    Effects: Initializes quantity-from-origin with std​::​forward<FwdQ>(q).
    template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> +constexpr quantity_point(FwdQ&& q, PO2); +
    Effects: Equivalent to: +quantity_point(quantity_point<Q::reference, PO2{}, typename Q::rep>{std::forward<FwdQ>(q), + PO2{}}) +
    template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> +constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); +
    Effects: If point_origin == QP​::​point_origin is true, +initializes quantity-from-origin with qp.quantity_ref_from(point_origin).
    Otherwise, initializes quantity-from-origin with qp - point_origin.
    template<QuantityPointLike QP> + requires see below +constexpr explicit(see below) quantity_point(const QP& qp); +
    Let Traits be quantity_point_like_traits<QP>.
    Effects: Initializes quantity-from-origin with +Traits::to_numerical_value(qp), get_unit(Traits::reference) +
    Remarks: The expression in the requires-clause is equivalent to: +(Traits::point_origin == point_origin) && + std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +
    +The expression inside explicit is equivalent to: +Traits::explicit_import || + !std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +

    5.7.7 Conversions [qty.pt.conv]

    template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> +constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; +
    Effects: Equivalent to: +if constexpr (std::is_same_v<NewPO, decltype(point_origin)>) + return *this; +else + return ::mp_units::quantity_point{*this - new_origin, new_origin}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; +
    Let converted-quantity-expr be an expression denoting +the function call to the corresponding member of quantity_ref_from(point_origin).
    Effects: Equivalent to: +return ::mp_units::quantity_point{converted-quantity-expr, point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { converted-quantity-expr; } +

    5.7.8 Quantity value observers [qty.pt.obs]

    template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr quantity_type& quantity_ref_from(PO2) & noexcept; +template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; +
    Returns: quantity-from-origin.
    template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } +constexpr Quantity auto quantity_from(PO2 rhs) const; + +template<QuantityPointOf<absolute_point_origin> QP> +constexpr Quantity auto quantity_from(const QP& rhs) const; +
    Effects: Equivalent to: +return *this - rhs;
    constexpr Quantity auto quantity_from_zero() const; +
    Effects: Equivalent to: +if constexpr (requires { unit.point-origin; }) { + // can lose the input unit + const auto q = quantity_from(unit.point-origin); + if constexpr (requires { q.in(unit); }) + // restore the unit + return q.in(unit); + else + return q; +} else + return quantity_from(absolute_point_origin); +

    5.7.9 Conversion operations [qty.pt.conv.ops]

    template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() const & noexcept(see below); +template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() && noexcept(see below); +
    Let Traits be quantity_point_like_traits<QP>.
    Let result-expr be +Traits::from_numerical_value(std::move(quantity-from-origin).numerical-value) +
    Returns: result-expr.
    Remarks: The expression in the requires-clause is equivalent to: +(point_origin == Traits::point_origin) && + std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +The expression inside explicit is equivalent to: +Traits::explicit_export || + !std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +Let T be +std​::​is_nothrow_copy_constructible_v for the first signature, and +std​::​is_nothrow_move_constructible_v for the second signature.
    The exception specification is equivalent to: +noexcept(result-expr) && T<rep> +

    5.7.10 Unary operations [qty.pt.unary.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; +template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; +
    Effects: Equivalent to +@qp.quantity-from-origin.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +requires { @qp.quantity-from-origin; } +
    constexpr quantity_point operator++(int) + requires see below; +constexpr quantity_point operator--(int) + requires see below; +
    Effects: Equivalent to: +return {quantity-from-origin@, PO};
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity-from-origin@; } +

    5.7.11 Compound assignment operations [qty.pt.assign.ops]

    template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); +template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); +
    Let @ be the operator.
    Effects: Equivalent to +qp.quantity-from-origin @ q.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity_type> && + requires { qp.quantity-from-origin @ q; } +

    5.7.12 Arithmetic operations [qty.pt.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +
    Effects: Equivalent to: +if constexpr (is-specialization-of<PO, zeroth_point_origin>()) + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q}; +else + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q, PO}; +
    Remarks: The expression in the requires-clause is equivalent to: +ReferenceOf<decltype(R2), PO.quantity-spec> && requires { + qp.quantity_ref_from(PO) @ q; +} +
    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> +friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; +
    Effects: Equivalent to: +return lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin) + + (lhs.point_origin - rhs.point_origin); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin); } +
    Recommended practice: The subtraction of two equal origins is not evaluated.
    template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(const QP& qp, PO2 po); +template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(PO2 po, const QP& qp); +
    Effects: For the first signature, +equivalent to: +if constexpr (point_origin == po) + return qp.quantity_ref_from(point_origin); +else if constexpr (is-derived-from-specialization-of<PO2, + ::mp_units::absolute_point_origin>()) { + return qp.quantity_ref_from(point_origin) + (qp.point_origin - qp.absolute_point_origin); +} else { + return qp.quantity_ref_from(point_origin) - + po.quantity-point.quantity_ref_from(po.quantity-point.point_origin) + + (qp.point_origin - po.quantity-point.point_origin); +} +
    +For the second signature, +equivalent to: return -(qp - po);
    Remarks: The expression in the requires-clause is equivalent to: +QuantityPointOf<quantity_point, PO2{}> && + ReferenceOf<decltype(auto(reference)), PO2::quantity-spec> +
    Recommended practice: The subtraction of two equal origins is not evaluated.

    5.7.13 Comparison [qty.pt.cmp]

    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr bool operator==(const QP& lhs, const QP2& rhs); +template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +
    Let @ be the operator, and +let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Effects: Equivalent to: +return lhs - lhs.absolute_point_origin @ rhs - rhs.absolute_point_origin; +
    Remarks: The expression in the requires-clause is equivalent to: +C<quantity_type, typename QP2::quantity_type> +
    Recommended practice: If the origins are equal, instead evaluate +lhs.quantity_ref_from(point_origin) @ rhs.quantity_ref_from(QP2::point_origin) +

    5.7.14 Construction helper point [qty.point]

    namespace mp_units { + +template<Reference R> +struct point_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity_point{quantity{std​::​forward<FwdRep>(lhs), R{}}};

    5.7.15 Non-member conversions [qty.pt.non.mem.conv]

    template<QuantityPoint ToQP, typename FwdFromQP, + QuantityPoint FromQP = std::remove_cvref_t<FwdFromQP>> + requires see below +constexpr QuantityPoint auto sudo-cast(FwdFromQP&& qp); +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToU)) +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires RepresentationOf<ToRep, QP::quantity_spec> && + std::constructible_from<ToRep, typename QP::rep> +constexpr quantity_point<QP::reference, QP::point_origin, ToRep> value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return {value_cast<ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), QP::point_origin}; +
    template<Unit auto ToU, Representation ToRep, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +template<Representation ToRep, Unit auto ToU, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU, ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec> && +std::constructible_from<ToRep, typename QP::rep> +
    template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQ::unit)) && (ToQ::quantity_spec == QP::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToQ>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQP::unit)) && + (ToQP::quantity_spec == QP::quantity_spec) && + (same-absolute-point-origins(ToQP::point_origin, QP::point_origin)) && + std::constructible_from<typename ToQP::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return sudo-cast<ToQP>(std​::​forward<FwdQP>(qp));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires QuantitySpecCastableTo<QP::quantity_spec, ToQS> +constexpr QuantityPoint auto quantity_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin), + QP::point_origin}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.like.html b/HEAD/api_reference/gen/qty.pt.like.html new file mode 100644 index 00000000..416f4c10 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.like.html @@ -0,0 +1,10 @@ +[qty.pt.like]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.3 Interoperability [qty.pt.like]

    template<typename T> +concept QuantityPointLike = + !QuantityPoint<T> && + qty-like-impl<T, quantity_point_like_traits> && // see [qty.like] + requires { + typename quantity_point<quantity_point_like_traits<T>::reference, + quantity_point_like_traits<T>::point_origin, + typename quantity_point_like_traits<T>::rep>; + }; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.non.mem.conv.html b/HEAD/api_reference/gen/qty.pt.non.mem.conv.html new file mode 100644 index 00000000..c1df916d --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.non.mem.conv.html @@ -0,0 +1,51 @@ +[qty.pt.non.mem.conv]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.15 Non-member conversions [qty.pt.non.mem.conv]

    template<QuantityPoint ToQP, typename FwdFromQP, + QuantityPoint FromQP = std::remove_cvref_t<FwdFromQP>> + requires see below +constexpr QuantityPoint auto sudo-cast(FwdFromQP&& qp); +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToU)) +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires RepresentationOf<ToRep, QP::quantity_spec> && + std::constructible_from<ToRep, typename QP::rep> +constexpr quantity_point<QP::reference, QP::point_origin, ToRep> value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return {value_cast<ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), QP::point_origin}; +
    template<Unit auto ToU, Representation ToRep, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +template<Representation ToRep, Unit auto ToU, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU, ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec> && +std::constructible_from<ToRep, typename QP::rep> +
    template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQ::unit)) && (ToQ::quantity_spec == QP::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToQ>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQP::unit)) && + (ToQP::quantity_spec == QP::quantity_spec) && + (same-absolute-point-origins(ToQP::point_origin, QP::point_origin)) && + std::constructible_from<typename ToQP::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return sudo-cast<ToQP>(std​::​forward<FwdQP>(qp));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires QuantitySpecCastableTo<QP::quantity_spec, ToQS> +constexpr QuantityPoint auto quantity_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin), + QP::point_origin}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.obs.html b/HEAD/api_reference/gen/qty.pt.obs.html new file mode 100644 index 00000000..f272df04 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.obs.html @@ -0,0 +1,26 @@ +[qty.pt.obs]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.8 Quantity value observers [qty.pt.obs]

    template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr quantity_type& quantity_ref_from(PO2) & noexcept; +template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; +
    Returns: quantity-from-origin.
    template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } +constexpr Quantity auto quantity_from(PO2 rhs) const; + +template<QuantityPointOf<absolute_point_origin> QP> +constexpr Quantity auto quantity_from(const QP& rhs) const; +
    Effects: Equivalent to: +return *this - rhs;
    constexpr Quantity auto quantity_from_zero() const; +
    Effects: Equivalent to: +if constexpr (requires { unit.point-origin; }) { + // can lose the input unit + const auto q = quantity_from(unit.point-origin); + if constexpr (requires { q.in(unit); }) + // restore the unit + return q.in(unit); + else + return q; +} else + return quantity_from(absolute_point_origin); +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.orig.concepts.html b/HEAD/api_reference/gen/qty.pt.orig.concepts.html new file mode 100644 index 00000000..9f07135c --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.orig.concepts.html @@ -0,0 +1,10 @@ +[qty.pt.orig.concepts]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.2 Concepts [qty.pt.orig.concepts]

    template<typename T> +concept PointOrigin = SymbolicConstant<T> && std::derived_from<T, point-origin-interface>; + +template<typename T, auto QS> +concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<decltype(QS), T::quantity-spec>; + +template<typename T, auto V> +concept SameAbsolutePointOriginAs = // exposition only + PointOrigin<T> && PointOrigin<decltype(V)> && same-absolute-point-origins(T{}, V); +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.orig.general.html b/HEAD/api_reference/gen/qty.pt.orig.general.html new file mode 100644 index 00000000..005616c3 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.orig.general.html @@ -0,0 +1,2 @@ +[qty.pt.orig.general]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.1 General [qty.pt.orig.general]

    This subclause specifies the components +for defining the origin of an affine space.
    An origin is a point from which measurements (IEC 60050, 112-04-01) take place.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.orig.html b/HEAD/api_reference/gen/qty.pt.orig.html new file mode 100644 index 00000000..d9455df5 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.orig.html @@ -0,0 +1,135 @@ +[qty.pt.orig]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.1 General [qty.pt.orig.general]

    This subclause specifies the components +for defining the origin of an affine space.
    An origin is a point from which measurements (IEC 60050, 112-04-01) take place.

    5.7.2.2 Concepts [qty.pt.orig.concepts]

    template<typename T> +concept PointOrigin = SymbolicConstant<T> && std::derived_from<T, point-origin-interface>; + +template<typename T, auto QS> +concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<decltype(QS), T::quantity-spec>; + +template<typename T, auto V> +concept SameAbsolutePointOriginAs = // exposition only + PointOrigin<T> && PointOrigin<decltype(V)> && same-absolute-point-origins(T{}, V); +

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.1 Absolute [qty.abs.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct absolute_point_origin : point-origin-interface { + static constexpr QuantitySpec auto quantity-spec = QS; // exposition only +}; + +} +
    An absolute origin is an origin +chosen by convention and not defined in terms of another origin.
    A specialization of absolute_point_origin is used as a base type when defining an absolute origin.
    QS is the quantity the origin represents.

    5.7.2.3.2 Relative [qty.rel.pt.orig]

    namespace mp_units { + +template<QuantityPoint auto QP> +struct relative_point_origin : point-origin-interface { + static constexpr QuantityPoint auto quantity-point = QP; // exposition only + static constexpr QuantitySpec auto quantity-spec = see below; // exposition only + static constexpr PointOrigin auto absolute-point-origin = // exposition only + QP.absolute_point_origin; +}; + +} +
    A relative origin is an origin +of a subspace (IEC 60050, 102-03-03).
    A specialization of relative_point_origin is used as a base type when defining a relative origin O.
    O is offset from QP.absolute_point_origin by QP.quantity_from_zero().
    The member quantity-spec is equal to +QP.point_origin.quantity-spec if +QuantityKindSpec<decltype(auto(QP.quantity-spec))> + +is satisfied, and +to QP.quantity-spec otherwise.

    5.7.2.3.3 Zeroth [qty.zeroth.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct zeroth_point_origin_ final : absolute_point_origin<QS> {}; + +} +
    zeroth_point_origin_<QS> represents an origin +chosen by convention as the value 0 of the quantity QS.

    5.7.2.4 Operations [qty.pt.orig.ops]

    namespace mp_units { + +struct point-origin-interface { + template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); + template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); + + template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> + friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; + + template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below + friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); + + template<PointOrigin PO1, PointOrigin PO2> + friend consteval bool operator==(PO1 po1, PO2 po2); +}; + +} +
    template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); +template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); +
    Effects: Equivalent to: +return quantity_point{std​::​forward<FwdQ>(q), PO{}};
    template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> +friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; +
    Effects: Equivalent to: +return po + -q;
    template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below +friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>()) { + return po1 - po2.quantity-point; +} else if constexpr (is-derived-from-specialization-of<PO2, absolute_point_origin>()) { + return po1.quantity-point - po2; +} else { + return po1.quantity-point - po2.quantity-point; +} +
    Remarks: The expression in the requires-clause is equivalent to: +QuantitySpecOf<decltype(auto(PO1::quantity-spec)), PO2::quantity-spec> && + (is-derived-from-specialization-of<PO1, relative_point_origin>() || + is-derived-from-specialization-of<PO2, relative_point_origin>()) +
    template<PointOrigin PO1, PointOrigin PO2> +friend consteval bool operator==(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return std::is_same_v<PO1, PO2> || + (is-specialization-of<PO1, zeroth_point_origin>() && + is-specialization-of<PO2, zeroth_point_origin>() && + interconvertible(po1.quantity-spec, po2.quantity-spec)); +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return PO1::quantity-point == PO2::quantity-point; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO1::quantity-point.quantity_from_zero()); +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO2::quantity-point.quantity_from_zero()); +

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.1 Same absolute [qty.same.abs.pt.origs]

    template<PointOrigin PO1, PointOrigin PO2> +consteval bool same-absolute-point-origins(PO1 po1, PO2 po2); // exposition only +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return po1 == po2; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1.absolute-point-origin == po2.absolute-point-origin; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return po1.absolute-point-origin == po2; +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1 == po2.absolute-point-origin; +else + return false; +

    5.7.2.5.2 Default [qty.def.pt.orig]

    template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); +
    Effects: Equivalent to: +if constexpr (requires { get_unit(R{}).point-origin; }) + return get_unit(R{}).point-origin; +else + return zeroth_point_origin<get_quantity_spec(R{})>; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.orig.ops.html b/HEAD/api_reference/gen/qty.pt.orig.ops.html new file mode 100644 index 00000000..873cf1a3 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.orig.ops.html @@ -0,0 +1,70 @@ +[qty.pt.orig.ops]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.4 Operations [qty.pt.orig.ops]

    namespace mp_units { + +struct point-origin-interface { + template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); + template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); + + template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> + friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; + + template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below + friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); + + template<PointOrigin PO1, PointOrigin PO2> + friend consteval bool operator==(PO1 po1, PO2 po2); +}; + +} +
    template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); +template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); +
    Effects: Equivalent to: +return quantity_point{std​::​forward<FwdQ>(q), PO{}};
    template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> +friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; +
    Effects: Equivalent to: +return po + -q;
    template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below +friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>()) { + return po1 - po2.quantity-point; +} else if constexpr (is-derived-from-specialization-of<PO2, absolute_point_origin>()) { + return po1.quantity-point - po2; +} else { + return po1.quantity-point - po2.quantity-point; +} +
    Remarks: The expression in the requires-clause is equivalent to: +QuantitySpecOf<decltype(auto(PO1::quantity-spec)), PO2::quantity-spec> && + (is-derived-from-specialization-of<PO1, relative_point_origin>() || + is-derived-from-specialization-of<PO2, relative_point_origin>()) +
    template<PointOrigin PO1, PointOrigin PO2> +friend consteval bool operator==(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return std::is_same_v<PO1, PO2> || + (is-specialization-of<PO1, zeroth_point_origin>() && + is-specialization-of<PO2, zeroth_point_origin>() && + interconvertible(po1.quantity-spec, po2.quantity-spec)); +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return PO1::quantity-point == PO2::quantity-point; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO1::quantity-point.quantity_from_zero()); +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO2::quantity-point.quantity_from_zero()); +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.orig.types.html b/HEAD/api_reference/gen/qty.pt.orig.types.html new file mode 100644 index 00000000..f9362a21 --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.orig.types.html @@ -0,0 +1,34 @@ +[qty.pt.orig.types]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.1 Absolute [qty.abs.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct absolute_point_origin : point-origin-interface { + static constexpr QuantitySpec auto quantity-spec = QS; // exposition only +}; + +} +
    An absolute origin is an origin +chosen by convention and not defined in terms of another origin.
    A specialization of absolute_point_origin is used as a base type when defining an absolute origin.
    QS is the quantity the origin represents.

    5.7.2.3.2 Relative [qty.rel.pt.orig]

    namespace mp_units { + +template<QuantityPoint auto QP> +struct relative_point_origin : point-origin-interface { + static constexpr QuantityPoint auto quantity-point = QP; // exposition only + static constexpr QuantitySpec auto quantity-spec = see below; // exposition only + static constexpr PointOrigin auto absolute-point-origin = // exposition only + QP.absolute_point_origin; +}; + +} +
    A relative origin is an origin +of a subspace (IEC 60050, 102-03-03).
    A specialization of relative_point_origin is used as a base type when defining a relative origin O.
    O is offset from QP.absolute_point_origin by QP.quantity_from_zero().
    The member quantity-spec is equal to +QP.point_origin.quantity-spec if +QuantityKindSpec<decltype(auto(QP.quantity-spec))> + +is satisfied, and +to QP.quantity-spec otherwise.

    5.7.2.3.3 Zeroth [qty.zeroth.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct zeroth_point_origin_ final : absolute_point_origin<QS> {}; + +} +
    zeroth_point_origin_<QS> represents an origin +chosen by convention as the value 0 of the quantity QS.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.orig.utils.html b/HEAD/api_reference/gen/qty.pt.orig.utils.html new file mode 100644 index 00000000..b783e98e --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.orig.utils.html @@ -0,0 +1,23 @@ +[qty.pt.orig.utils]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.1 Same absolute [qty.same.abs.pt.origs]

    template<PointOrigin PO1, PointOrigin PO2> +consteval bool same-absolute-point-origins(PO1 po1, PO2 po2); // exposition only +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return po1 == po2; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1.absolute-point-origin == po2.absolute-point-origin; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return po1.absolute-point-origin == po2; +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1 == po2.absolute-point-origin; +else + return false; +

    5.7.2.5.2 Default [qty.def.pt.orig]

    template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); +
    Effects: Equivalent to: +if constexpr (requires { get_unit(R{}).point-origin; }) + return get_unit(R{}).point-origin; +else + return zeroth_point_origin<get_quantity_spec(R{})>; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.static.html b/HEAD/api_reference/gen/qty.pt.static.html new file mode 100644 index 00000000..5a40a6bc --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.static.html @@ -0,0 +1,7 @@ +[qty.pt.static]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.5 Static member functions [qty.pt.static]

    static constexpr quantity_point min() noexcept + requires see below; +static constexpr quantity_point max() noexcept + requires see below; +
    Let F be one of min and max.
    Returns: {quantity_type​::​F(), PO}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity_type::F(); } +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.syn.html b/HEAD/api_reference/gen/qty.pt.syn.html new file mode 100644 index 00000000..fe3b01cc --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.syn.html @@ -0,0 +1,199 @@ +[qty.pt.syn]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.4 Class template quantity_point [qty.pt.syn]

    namespace mp_units { + +template<typename T> +concept QuantityPoint = (is-derived-from-specialization-of<T, quantity_point>()); + +template<typename QP, auto V> +concept QuantityPointOf = + QuantityPoint<QP> && (QuantitySpecOf<decltype(auto(QP::quantity_spec)), V> || + SameAbsolutePointOriginAs<decltype(auto(QP::absolute_point_origin)), V>); + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point { +public: + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + static constexpr PointOrigin auto absolute_point_origin = see below; + static constexpr PointOrigin auto point_origin = PO; + using rep = Rep; + using quantity_type = quantity<reference, Rep>; + + quantity_type quantity-from-origin; // exposition only + + // [qty.pt.static], static member functions + static constexpr quantity_point min() noexcept + requires see below; + static constexpr quantity_point max() noexcept + requires see below; + + // [qty.pt.cons], constructors and assignment + + quantity_point() = default; + quantity_point(const quantity_point&) = default; + quantity_point(quantity_point&&) = default; + ~quantity_point() = default; + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) + constexpr explicit quantity_point(FwdQ&& q); + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> + constexpr quantity_point(FwdQ&& q, decltype(PO)); + + template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> + constexpr quantity_point(FwdQ&& q, PO2); + + template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> + constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); + + template<QuantityPointLike QP> + requires see below + constexpr explicit(see below) quantity_point(const QP& qp); + + quantity_point& operator=(const quantity_point&) = default; + quantity_point& operator=(quantity_point&&) = default; + + // [qty.pt.conv], conversions + + template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> + constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + // [qty.pt.obs], quantity value observers + + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr quantity_type& quantity_ref_from(PO2) & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + void quantity_ref_from(PO2) const && = delete; + + template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } + constexpr Quantity auto quantity_from(PO2) const; + + template<QuantityPointOf<absolute_point_origin> QP> + constexpr Quantity auto quantity_from(const QP&) const; + + constexpr Quantity auto quantity_from_zero() const; + + // [qty.pt.conv.ops], conversion operations + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() const & noexcept(see below); + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() && noexcept(see below); + + // [qty.pt.unary.ops], unary operations + + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; + + constexpr quantity_point operator++(int) + requires see below; + constexpr quantity_point operator--(int) + requires see below; + + // [qty.pt.assign.ops], compound assignment operations + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); + + // [qty.pt.arith.ops], arithmetic operations + + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; + + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(const QP& qp, PO2 po); + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(PO2 po, const QP& qp); + + // [qty.pt.cmp], comparison + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr bool operator==(const QP& lhs, const QP2& rhs); + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +}; + +template<Quantity Q> +explicit quantity_point(Q q) + -> quantity_point<Q::reference, default_point_origin(Q::reference), typename Q::rep>; + +template<Quantity Q, PointOriginFor<Q::quantity_spec> PO> +quantity_point(Q, PO) -> quantity_point<Q::reference, PO{}, typename Q::rep>; + +template<QuantityPointLike QP, typename Traits = quantity_point_like_traits<QP>> +explicit(quantity_point_like_traits<QP>::explicit_import) quantity_point(QP) + -> quantity_point<Traits::reference, Traits::point_origin, typename Traits::rep>; + +} +
    quantity_point<R, PO, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.
    The member absolute_point_origin is equal to PO if +is-derived-from-specialization-of<decltype(PO), absolute_point_origin>() + +is true, and +to PO.quantity-point.absolute_point_origin otherwise.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.pt.unary.ops.html b/HEAD/api_reference/gen/qty.pt.unary.ops.html new file mode 100644 index 00000000..12f2c30f --- /dev/null +++ b/HEAD/api_reference/gen/qty.pt.unary.ops.html @@ -0,0 +1,18 @@ +[qty.pt.unary.ops]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.10 Unary operations [qty.pt.unary.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; +template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; +
    Effects: Equivalent to +@qp.quantity-from-origin.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +requires { @qp.quantity-from-origin; } +
    constexpr quantity_point operator++(int) + requires see below; +constexpr quantity_point operator--(int) + requires see below; +
    Effects: Equivalent to: +return {quantity-from-origin@, PO};
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity-from-origin@; } +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ratio.html b/HEAD/api_reference/gen/qty.ratio.html new file mode 100644 index 00000000..be6d27f5 --- /dev/null +++ b/HEAD/api_reference/gen/qty.ratio.html @@ -0,0 +1,46 @@ +[qty.ratio]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.2 Ratio [qty.ratio]

    namespace mp_units { + +struct ratio { // exposition only + std::intmax_t num; + std::intmax_t den; + + consteval ratio(std::intmax_t n, std::intmax_t d = 1); + + friend consteval bool operator==(ratio, ratio) = default; + friend consteval auto operator<=>(ratio lhs, ratio rhs) { return (lhs - rhs).num <=> 0; } + + friend consteval ratio operator-(ratio r) { return {-r.num, r.den}; } + + friend consteval ratio operator+(ratio lhs, ratio rhs) + { + return {lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den}; + } + + friend consteval ratio operator-(ratio lhs, ratio rhs) { return lhs + (-rhs); } + + friend consteval ratio operator*(ratio lhs, ratio rhs); + + friend consteval ratio operator/(ratio lhs, ratio rhs) + { + return lhs * ratio{rhs.den, rhs.num}; + } +}; + +consteval bool is-integral(ratio r) { return r.num % r.den == 0; } + +consteval ratio common-ratio(ratio r1, ratio r2); + +} +
    ratio represents the rational number .
    Unless otherwise specified, +in the following descriptions, +let R(r) be std​::​ratio<N, D>, +where N and D are the values of r.num and r.den.
    consteval ratio(std::intmax_t n, std::intmax_t d = 1); +
    Let N and D be the values of n and d.
    Let R be std​::​ratio<N, D>.
    Effects: Equivalent to +R.
    Postconditions: num == R​::​num && den == R​::​den is true.
    friend consteval ratio operator*(ratio lhs, ratio rhs); +
    Let Res be std​::​ratio_multiply<R(lhs), R(rhs)>.
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};
    consteval ratio common-ratio(ratio r1, ratio r2); +
    Let Res be equal to +std::common_type<std::chrono::duration<int, R(r1)>, + std::chrono::duration<int, R(r2)>>::type::period +
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.real.cpo.html b/HEAD/api_reference/gen/qty.real.cpo.html new file mode 100644 index 00000000..a8174a8a --- /dev/null +++ b/HEAD/api_reference/gen/qty.real.cpo.html @@ -0,0 +1,8 @@ +[qty.real.cpo]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    The name mp_units​::​real denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​real(E) is ill-formed.
    • If auto(t.real()) is a valid expression whose type models Scalar, +mp_units​::​real(E) is expression-equivalent to auto(t.real()).
    • Otherwise, if T is a class or enumeration type and +auto(real(t)) is a valid expression whose type models Scalar +where the meaning of real is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​real(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​real(E) is ill-formed.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.cmp.html b/HEAD/api_reference/gen/qty.ref.cmp.html new file mode 100644 index 00000000..45db7541 --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.cmp.html @@ -0,0 +1,11 @@ +[qty.ref.cmp]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.8 Comparison [qty.ref.cmp]

    template<typename Q2, typename U2> +friend consteval bool operator==(reference, reference<Q2, U2>); +
    Returns: Q{} == Q2{} && U{} == U2{}.
    template<AssociatedUnit U2> +friend consteval bool operator==(reference, U2 u2); +
    Returns: Q{} == get_quantity_spec(u2) && U{} == u2.
    template<typename Q2, typename U2> +friend consteval bool convertible(reference, reference<Q2, U2>); +
    Returns: implicitly_convertible(Q{}, Q2{}) && convertible(U{}, U2{}).
    template<AssociatedUnit U2> +friend consteval bool convertible(reference, U2 u2); +
    Returns: implicitly_convertible(Q{}, get_quantity_spec(u2)) && convertible(U{}, u2).
    template<AssociatedUnit U1> +friend consteval bool convertible(U1 u1, reference); +
    Returns: implicitly_convertible(get_quantity_spec(u1), Q{}) && convertible(u1, U{}).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.concepts.html b/HEAD/api_reference/gen/qty.ref.concepts.html new file mode 100644 index 00000000..f55c9644 --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.concepts.html @@ -0,0 +1,6 @@ +[qty.ref.concepts]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.5 Concepts [qty.ref.concepts]

    template<typename T> +concept Reference = AssociatedUnit<T> || (is-specialization-of<T, reference>()); +
    A type T that satisfies Reference +represents the reference of a quantity (IEC 60050, 112-01-01).
    template<typename T, auto QS> +concept ReferenceOf = Reference<T> && QuantitySpecOf<decltype(get_quantity_spec(T{})), QS>; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.general.html b/HEAD/api_reference/gen/qty.ref.general.html new file mode 100644 index 00000000..ed40e3f7 --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.general.html @@ -0,0 +1,2 @@ +[qty.ref.general]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.1 General [qty.ref.general]

    Subclause [qty.ref] specifies the components +for describing the reference of a quantity (IEC 60050, 112-01-01).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.html b/HEAD/api_reference/gen/qty.ref.html new file mode 100644 index 00000000..06b7d07f --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.html @@ -0,0 +1,986 @@ +[qty.ref]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.1 General [qty.ref.general]

    Subclause [qty.ref] specifies the components +for describing the reference of a quantity (IEC 60050, 112-01-01).

    5.4.2 Dimension [qty.dim]

    5.4.2.1 General [qty.dim.general]

    Subclause [qty.dim] specifies the components +for defining the dimension of a quantity (IEC 60050, 112-01-11).

    5.4.2.2 Concepts [qty.dim.concepts]

    template<typename T> +concept Dimension = SymbolicConstant<T> && std::derived_from<T, dimension-interface>; + +template<typename T> +concept BaseDimension = // exposition only + Dimension<T> && (is-derived-from-specialization-of<T, base_dimension>()); + +template<typename T, auto D> +concept DimensionOf = Dimension<T> && Dimension<decltype(D)> && (T{} == D); +

    5.4.2.3 Types [qty.dim.types]

    namespace mp_units { + +template<symbol_text Symbol> +struct base_dimension : dimension-interface { + static constexpr auto symbol = Symbol; // exposition only +}; + +} +
    base_dimension is used +to define the dimension of a base quantity (IEC 60050, 112-01-08).
    Symbol is its symbolic representation.
    [Example 1: inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length; + — end example]
    namespace mp_units { + +template<typename... Expr> +struct derived-dimension-impl // exposition only + : expr-fractions<struct dimension_one, Expr...> {}; + +template<SymbolicConstant... Expr> +struct derived_dimension final : dimension-interface, derived-dimension-impl<Expr...> {}; + +} +
    derived_dimension is used by the library +to represent the dimension of a derived quantity (IEC 60050, 112-01-10).
    [Example 2: constexpr auto dim_acceleration = isq::speed.dimension / isq::dim_time; +int x = dim_acceleration; // error: cannot construct from + // derived_dimension<isq​::​dim_length, per<power<isq​::​dim_time, 2>>> + — end example]
    +A program that instantiates a specialization of derived_dimension +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +struct dimension_one final : dimension-interface, derived-dimension-impl<> {}; + +} +
    dimension_one represents the dimension of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.2.4 Operations [qty.dim.ops]

    namespace mp_units { + +struct dimension-interface { // exposition only + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator*(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator/(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator*(Lhs, Rhs); +
    Returns: expr-multiply<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator/(Lhs, Rhs); +
    Returns: expr-divide<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval Dimension auto inverse(Dimension auto d); +
    Returns: dimension_one / d.
    template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +
    Returns: expr-pow<Num, Den, derived_dimension, struct dimension_one>(d).
    consteval Dimension auto sqrt(Dimension auto d); +
    Returns: pow<1, 2>(d).
    consteval Dimension auto cbrt(Dimension auto d); +
    Returns: pow<1, 3>(d).

    5.4.2.5 Symbol formatting [qty.dim.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); +
    Effects: Equivalent to: +TBD. +

    5.4.3 Quantity specification [qty.spec]

    5.4.3.1 General [qty.spec.general]

    Subclause [qty.spec] specifies the components +for defining a quantity (IEC 60050, 112-01-01).

    5.4.3.2 Concepts [qty.spec.concepts]

    template<typename T> +concept QuantitySpec = SymbolicConstant<T> && std::derived_from<T, quantity-spec-interface>; + +template<typename T> +concept QuantityKindSpec = // exposition only + QuantitySpec<T> && is-specialization-of<T, kind_of_>(); + +template<typename T> +concept NamedQuantitySpec = // exposition only + QuantitySpec<T> && is-derived-from-specialization-of<T, quantity_spec>() && + (!QuantityKindSpec<T>); + +template<typename T> +concept DerivedQuantitySpec = // exposition only + QuantitySpec<T> && + (is-specialization-of<T, derived_quantity_spec>() || + (QuantityKindSpec<T> && + is-specialization-of<decltype(auto(T::quantity-spec)), derived_quantity_spec>())); + +template<auto Child, auto Parent> +concept ChildQuantitySpecOf = (is-child-of(Child, Parent)); // exposition only + +template<auto To, auto From> +concept NestedQuantityKindSpecOf = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && + (get_kind(From) != get_kind(To)) && ChildQuantitySpecOf<To, get_kind(From).quantity-spec>; + +template<auto From, auto To> +concept QuantitySpecConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && implicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecExplicitlyConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && explicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecCastableTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && castable(From, To); + +template<typename T, auto QS> +concept QuantitySpecOf = + QuantitySpec<T> && QuantitySpec<decltype(QS)> && QuantitySpecConvertibleTo<T{}, QS> && + !NestedQuantityKindSpecOf<T{}, QS> && + (QuantityKindSpec<T> || !NestedQuantityKindSpecOf<QS, T{}>); + +template<typename T> +concept QSProperty = (!QuantitySpec<T>); // exposition only +

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.1 Named [named.qty]

    namespace mp_units { + +struct is_kind {}; + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr BaseDimension auto dimension = Dim; + static constexpr quantity_character character = see below; +}; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = parent.equation; // exposition only, present only + // if the qualified-id parent.equation is valid and denotes an object + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> + requires QuantitySpecExplicitlyConvertibleTo<Eq, QS> +struct quantity_spec<QS, Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +} +
    A named quantity is a type that models NamedQuantitySpec.
    A specialization of quantity_spec is used as a base type when defining a named quantity.
    In the following descriptions, let Q be a named quantity defined with an alluded signature.
    The identifier of Q represents its quantity name (IEC 60050, 112-01-02).
    Let Ch be an enumerator value of quantity_character.
    The possible arguments to quantity_spec are +
    • ,
    • ,
    • , and
    • .
    If the first argument is a base quantity dimension, +then Q is that base quantity (IEC 60050, 112-01-08).
    If an argument is a quantity calculus (IEC 60050, 112-01-30) C, +then Q is implicitly convertible from C.
    If the first argument is a named quantity, +then Q is of its kind (IEC 60050, 112-01-04).
    The member character represents +the set of the numerical value of Q ([qty.char.traits]) +and is equal to +
    • Ch if specified,
    • otherwise, quantity_character​::​scalar for the first signature, and
    • otherwise, (BC).character, +where BC is the argument preceding Ch in the signatures above.
    is_kind specifies Q to start a new hierarchy tree of a kind.
    Optional arguments may appear in any order.
    [Example 1: // The first signature defines a base quantity. +inline constexpr struct length final : quantity_spec<dim_length> { +} length; // Length is a base quantity. + +// The second signature defines a derived quantity. +inline constexpr struct area final : quantity_spec<pow<2>(length)> { +} area; // An area equals length by length. + +// The third and fourth signatures add a leaf to a hierarchy of kinds. +inline constexpr struct width final : quantity_spec<length> { +} width; // Width is a kind of length. + +// The fourth signature also refines the calculus required for implicit conversions. +inline constexpr struct angular_measure final : + quantity_spec<dimensionless, arc_length / radius, is_kind> { +} angular_measure; // Requires an arc length per radius, not just any quantity of dimension one. + — end example]

    5.4.3.3.2 Derived [derived.qty]

    namespace mp_units { + +template<NamedQuantitySpec Q> +using to-dimension = decltype(auto(Q::dimension)); // exposition only + +template<typename... Expr> +struct derived-quantity-spec-impl : // exposition only + quantity-spec-interface, + expr-fractions<struct dimensionless, Expr...> { + using base-type = derived-quantity-spec-impl; + using base = expr-fractions<struct dimensionless, Expr...>; + + static constexpr Dimension auto dimension = + expr-map<to-dimension, derived_dimension, struct dimension_one>(base{}); + static constexpr quantity_character character = see below; +}; + +template<SymbolicConstant... Expr> +struct derived_quantity_spec final : derived-quantity-spec-impl<Expr...> {}; + +} +
    derived_quantity_spec is used by the library +to represent the result of a quantity calculus not equal to a named quantity.
    [Example 1: constexpr auto area = pow<2>(isq::length); +int x = area; // error: cannot construct from derived_quantity_spec<power<isq​::​length, 2>> + — end example]
    +A program that instantiates a specialization of derived_quantity_spec +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let +
    • Nums and Dens +be packs denoting the template arguments of +base​::​nums and base​::​dens, respectively,
    • QUANTITY-CHARACTER-OF(Pack) be +std::max({quantity_character::scalar, expr-type<Pack>::character...}) + +and
    • num_char be QUANTITY-CHARACTER-OF(Nums) and +den_char be QUANTITY-CHARACTER-OF(Dens).
    +The member character is equal to +quantity_character​::​scalar if num_char == den_char is true, and +std​::​max(num_char, den_char) otherwise.

    5.4.3.3.3 Base quantity of dimension one [dimless.qty]

    namespace mp_units { + +struct dimensionless final : quantity_spec<derived_quantity_spec<>> {}; + +} +
    dimensionless represents the base quantity of dimension one (IEC 60050, 112-01-13).

    5.4.3.3.4 Kind of [kind.of.qty]

    namespace mp_units { + +template<QuantitySpec Q> + requires(!QuantityKindSpec<Q>) && (get-kind-tree-root(Q{}) == Q{}) +struct kind_of_ final : Q::base-type { + using base-type = kind_of_; // exposition only + static constexpr auto quantity-spec = Q{}; // exposition only +}; + +} +
    kind_of<Q> represents a kind of quantity (IEC 60050, 112-01-04) Q.

    5.4.3.4 Utilities [qty.spec.utils]

    template<QuantitySpec auto... From, QuantitySpec Q> +consteval QuantitySpec auto clone-kind-of(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr ((... && QuantityKindSpec<decltype(From)>)) + return kind_of<Q{}>; +else + return q; +
    template<QuantitySpec Q> +consteval auto remove-kind(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr (QuantityKindSpec<Q>) + return Q::quantity-spec; +else + return q; +
    template<QuantitySpec QS, Unit U> + requires(!AssociatedUnit<U>) || UnitOf<U, QS{}> +consteval Reference auto make-reference(QS, U u); // exposition only +
    Effects: Equivalent to: +if constexpr (requires { requires get_quantity_spec(U{}) == QS{}; }) + return u; +else + return reference<QS, U>{}; +

    5.4.3.5 Operations [qty.spec.ops]

    namespace mp_units { + +struct quantity-spec-interface { // exposition only + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); + + template<typename Self, UnitOf<Self{}> U> + consteval Reference auto operator[](this Self self, U u); + + template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> + constexpr Quantity auto operator()(this Self self, FwdQ&& q); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-multiply<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-divide<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<typename Self, UnitOf<Self{}> U> +consteval Reference auto operator[](this Self self, U u); +
    Returns: make-reference(self, u).
    template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> +constexpr Quantity auto operator()(this Self self, FwdQ&& q); +
    Returns: quantity{std::forward<FwdQ>(q).numerical-value, make-reference(self, Q::unit)} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval QuantitySpec auto inverse(QuantitySpec auto q); +
    Returns: dimensionless / q.
    template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +
    Returns: clone-kind-of<Q{}>( + expr-pow<Num, Den, derived_quantity_spec, struct dimensionless>(remove-kind(q))); +
    consteval QuantitySpec auto sqrt(QuantitySpec auto q); +
    Returns: pow<1, 2>(q).
    consteval QuantitySpec auto cbrt(QuantitySpec auto q); +
    Returns: pow<1, 3>(q).

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.1 Conversion [qty.spec.conv]

    consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); +
    Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).

    5.4.3.6.2 Get kind [qty.get.kind]

    template<QuantitySpec Q> +consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only +
    Returns:
    • If QuantityKindSpec<Q> is true, +returns remove-kind(q).
    • Otherwise, if +is-derived-from-specialization-of<Q, quantity_spec>() +is true, and +the specialization of Q​::​quantity_spec has a template argument equal to is_kind, +returns q.
    • Otherwise, if Q​::​parent is a valid expression, +returns get-kind-tree-root(Q​::​parent).
    • Otherwise, if DerivedQuantitySpec<Q> is true, +returns +expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) + +where to-kind is defined as follows: +template<QuantitySpec Q> +using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only +
    • Otherwise, returns q.
    template<QuantitySpec Q> +consteval QuantityKindSpec auto get_kind(Q); +
    Returns: kind_of<get-kind-tree-root(Q{})>.

    5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

    consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; +
    Let +
    • q1 be qs...[0],
    • q2 be qs...[1],
    • Q1 be decltype(q1),
    • Q2 be decltype(q2), and
    • rest be a pack denoting the elements of qs without q1 and q2.
    Effects: Equivalent to: +if constexpr (sizeof...(qs) == 1) + return q1; +else if constexpr (sizeof...(qs) == 2) { + using QQ1 = decltype(remove-kind(q1)); + using QQ2 = decltype(remove-kind(q2)); + + if constexpr (std::is_same_v<Q1, Q2>) + return q1; + else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) + return QQ1{}; + else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) + return QQ2{}; + else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || + (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && + implicitly_convertible(Q1{}, Q2{}))) + return q2; + else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || + (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && + implicitly_convertible(Q2{}, Q1{}))) + return q1; + else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) + return *common_base; + else if constexpr (implicitly_convertible(Q1{}, Q2{})) + return q2; + else if constexpr (implicitly_convertible(Q2{}, Q1{})) + return q1; + else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), + get-kind-tree-root(Q2{}))) + return get-kind-tree-root(q2); + else + return get-kind-tree-root(q1); +} else + return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(qs) != 0 && + (sizeof...(qs) == 1 || + (sizeof...(qs) == 2 && + (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || + QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || + requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); })) +

    5.4.3.6.4 Get common base [qty.get.common.base]

    In this subclause and [qty.is.child.of], +let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple +, +where par is parent.
    template<QuantitySpec auto A, QuantitySpec auto B> +consteval auto get-common-base(); // exposition only +
    Let +
    • be the number of elements in h(A),
    • be the number of elements in h(B),
    • s be ,
    • A be a tuple of the last s elements of h(A), and
    • B be a tuple of the last s elements of h(B).
    Effects: Looks for x, the first pair-wise equal element in A and B.
    Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.

    5.4.3.6.5 Is child of [qty.is.child.of]

    template<QuantitySpec Child, QuantitySpec Parent> +consteval bool is-child-of(Child ch, Parent p); // exposition only +
    Returns: If h(p) has more elements than h(ch), returns false.
    Otherwise, let C be a tuple of the last s elements of h(ch), +where s is the number of elements in h(p).
    Returns == p.

    5.4.4 Unit [qty.unit]

    5.4.4.1 General [qty.unit.general]

    Subclause [qty.unit] specifies the components +for defining a unit of measurement (IEC 60050, 112-01-14).

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.1 General [qty.unit.mag.general]

    Subclause [qty.unit.mag] specifies the components +used to represent the numerical value (IEC 60050, 112-01-29) of a unit +with support for powers (IEC 60050, 102-02-08) of real numbers (IEC 60050, 102-02-05).

    5.4.4.2.2 Concepts [qty.unit.mag.concepts]

    template<typename T> +concept MagConstant = SymbolicConstant<T> && is-derived-from-specialization-of<T, mag_constant>(); + +template<typename T> +concept UnitMagnitude = (is-specialization-of<T, unit-magnitude>()); + +template<typename T> +concept MagArg = std::integral<T> || MagConstant<T>; // exposition only +

    5.4.4.2.3 Types [qty.unit.mag.types]

    namespace mp_units { + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant { + static constexpr auto symbol = Symbol; // exposition only + static constexpr long double value = Value; // exposition only +}; + +} +
    A specialization of mag_constant represents a real number (IEC 60050, 102-02-05).
    Symbol is its symbol, and +Value is (an approximation of) its value.
    namespace mp_units { + +template<auto... Ms> +struct unit-magnitude { // exposition only + // [qty.unit.mag.ops], operations + + template<UnitMagnitude M> + friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); + + friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); + + template<UnitMagnitude Rhs> + friend consteval bool operator==(unit-magnitude, Rhs); + + template<int Num, int Den = 1> + friend consteval auto pow(unit-magnitude); // exposition only + + // [qty.unit.mag.utils], utilities + + friend consteval bool is-positive-integral-power(unit-magnitude); // exposition only + + template<auto... Ms2> + friend consteval auto common-magnitude(unit-magnitude, // exposition only + unit-magnitude<Ms2...>); +}; + +} +
    A specialization of unit-magnitude +represents the product of its template arguments.
    For the purposes of specifying the implementation-defined limits, +let the representation of the terms of unit-magnitude be the structure +struct { + ratio exp; + base-type base; +}; + +representing the number , +where base-type is a model of MagArg.
    • There is a single term for each base-type.
    • exp.num is not expanded into base.
      [Note 1: 
      is not permitted.
      — end note]
    • exp.den can reduce the base.
      [Note 2: 
      is permitted.
      — end note]
    • If the result of an operation on std​::​intmax_t values is undefined, +the behavior is +implementation-defined.

    5.4.4.2.4 Operations [qty.unit.mag.ops]

    template<UnitMagnitude M> +friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); +
    Returns:
    • If sizeof...(Ms) == 0 is true, returns rhs.
    • Otherwise, if std​::​is_same_v<M, unit-magnitude<>>, returns lhs.
    • Otherwise, returns an unspecified value equal to lhs ×rhs.
    friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); +
    Returns: lhs * pow<-1>(rhs).
    template<UnitMagnitude Rhs> +friend consteval bool operator==(unit-magnitude, Rhs); +
    Returns: std​::​is_same_v<unit-magnitude, Rhs>.
    template<int Num, int Den = 1> +friend consteval auto pow(unit-magnitude base); // exposition only +
    Returns:
    • If Num == 0 is true, returns unit-magnitude<>{}.
    • Otherwise, returns an unspecified value equal to .
    template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; +
    Constraints: V is greater than 0.
    Effects: If MagConstant<decltype(V)> is satisfied, +initializes mag with unit-magnitude<V>{}.
    Otherwise, initializes mag with +an unspecified value equal to V.
    template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; +
    Effects: Initializes mag_ratio with +an unspecified value equal to .
    template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = pow<Num, Den>(mag<Base>); +
    Constraints: Base is greater than 0.

    5.4.4.2.5 Utilities [qty.unit.mag.utils]

    friend consteval bool is-positive-integral-power(unit-magnitude x); // exposition only +
    Returns: false if x has a negative or rational exponent, and +true otherwise.
    template<auto... Ms2> +friend consteval auto common-magnitude(unit-magnitude, unit-magnitude<Ms2...>); // exposition only +
    Returns: The largest magnitude C +such that each input magnitude is expressible +by only positive powers relative to C.

    5.4.4.3 Traits [qty.unit.traits]

    template<Unit auto U> +constexpr bool space_before_unit_symbol = true; +
    The formatting functions ([qty.unit.sym.fmt]) use space_before_unit_symbol +to determine whether there is a space +between the numerical value and the unit symbol.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize space_before_unit_symbol +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.4.4.4 Concepts [qty.unit.concepts]

    template<typename T> +concept Unit = SymbolicConstant<T> && std::derived_from<T, unit-interface>; + +template<typename T> +concept PrefixableUnit = Unit<T> && is-derived-from-specialization-of<T, named_unit>(); + +template<typename T> +concept AssociatedUnit = Unit<U> && has-associated-quantity(U{}); + +template<typename U, auto QS> +concept UnitOf = AssociatedUnit<U> && QuantitySpec<decltype(QS)> && + QuantitySpecConvertibleTo<get_quantity_spec(U{}), QS> && + (get_kind(QS) == get_kind(get_quantity_spec(U{})) || + !NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>); + +template<auto From, auto To> +concept UnitConvertibleTo = // exposition only + Unit<decltype(From)> && Unit<decltype(To)> && (convertible(From, To)); + +template<typename U, auto FromU, auto QS> +concept UnitCompatibleWith = // exposition only + Unit<U> && Unit<decltype(FromU)> && QuantitySpec<decltype(QS)> && + (!AssociatedUnit<U> || UnitOf<U, QS>) && UnitConvertibleTo<FromU, U{}>; + +template<typename T> +concept OffsetUnit = Unit<T> && requires { T::point-origin; }; // exposition only + +template<typename From, typename To> +concept PotentiallyConvertibleTo = // exposition only + Unit<From> && Unit<To> && + ((AssociatedUnit<From> && AssociatedUnit<To> && + implicitly_convertible(get_quantity_spec(From{}), get_quantity_spec(To{}))) || + (!AssociatedUnit<From> && !AssociatedUnit<To>)); +

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.1 Canonical [qty.canon.unit]

    namespace mp_units { + +template<UnitMagnitude M, Unit U> +struct canonical-unit { // exposition only + M mag; + U reference_unit; +}; + +} +
    canonical-unit represents a unit expressed in terms of base units (IEC 60050, 112-01-18).
    [Note 1: 
    Other types representing units are equal only if they have the same type.
    canonical-unit is used to implement binary relations other than equality.
    — end note]
    reference_unit is simplified ([qty.sym.expr.algos]).
    consteval auto get-canonical-unit(Unit auto u); // exposition only +
    Returns: The instantiation of canonical-unit for u.

    5.4.4.5.2 Scaled [qty.scaled.unit]

    namespace mp_units { + +template<UnitMagnitude auto M, Unit U> + requires(M != unit-magnitude<>{} && M != mag<1>) +struct scaled_unit final : unit-interface { + using base-type = scaled_unit; // exposition only + static constexpr UnitMagnitude auto mag = M; // exposition only + static constexpr U reference-unit{}; // exposition only + static constexpr auto point-origin = U::point_origin; // exposition only, present only + // if the qualified-id U​::​point_origin is valid and denotes an object +}; + +} +
    scaled_unit<M, U> is used by the library +to represent the unit M ×U.

    5.4.4.5.3 Named [qty.named.unit]

    namespace mp_units { + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS, PO> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol> + requires(!Symbol.empty()) +struct named_unit<Symbol> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U> + requires(!Symbol.empty()) +struct named_unit<Symbol, U> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires(!Symbol.empty()) +struct named_unit<Symbol, U, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +} +
    A named unit is a type that models PrefixableUnit.
    A specialization of named_unit is used as a base type when defining a named unit.
    In the following descriptions, let U be a named unit defined with an alluded signature.
    The identifier of U represents +its unit name (IEC 60050, 112-01-15) +or special unit name (IEC 60050, 112-01-16).
    Symbol is its unit symbol (IEC 60050, 112-01-17).
    The possible arguments to named_unit are +
    • ,
    • ,
    • , and
    • .
    The first signature defines the unit of a base quantity +without a unit prefix (IEC 60050, 112-01-26).
    The second signature defines a unit +that can be reused by several base quantities.
    The third and fourth signatures with a unit expression argument E +define U as implicitly convertible from E.
    The first and fourth signatures with a kind of quantity (IEC 60050, 112-01-04) Q +also restrict U to Q.
    A point origin argument specifies the default point origin of U ([qty.pt.syn]).
    [Example 1: // 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; // . + +// The fourth signature also further restricts the kind of quantity. +inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { +} hertz; // Hz can't measure becquerel, activity, + // or any other quantity with dimension + // that isn't a kind of frequency. + — end example]

    5.4.4.5.4 Prefixed [qty.prefixed.unit]

    namespace mp_units { + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires(!Symbol.empty()) +struct prefixed_unit : decltype(M * U)::base-type { + using base-type = prefixed_unit; // exposition only + static constexpr auto symbol = Symbol + U.symbol; // exposition only +}; + +} +
    prefixed_unit<Symbol, M, U> represents the unit U with a unit prefix (IEC 60050, 112-01-26).
    Symbol is the symbol of the unit prefix.
    M is the factor of the unit prefix.
    A specialization of prefixed_unit is used as a base type when defining a unit prefix.
    [Example 1: template<PrefixableUnit auto U> +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + +template<PrefixableUnit auto U> +constexpr kilo_<U> kilo; + +inline constexpr auto kilogram = kilo<si::gram>; + — end example]

    5.4.4.5.5 Common [qty.common.unit]

    namespace mp_units { + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit final : decltype(get-common-scaled-unit(U1{}, U2{}, Rest{}...))::base-type +{ + using base-type = common_unit; // exposition only + static constexpr auto common-unit = // exposition only + get-common-scaled-unit(U1{}, U2{}, Rest{}...); +}; + +} +
    common_unit is used by the library +to encapsulate a conversion factor between units (IEC 60050, 112-01-33) +common to the operands of quantity addition.
    [Example 1: 
    The result of 1 * km + 1 * mi +has a common unit +encapsulated by common_unit<mi, km>.
    — end example]
    +A program that instantiates a specialization of common_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    template<Unit U1, Unit U2, Unit... Rest> +consteval Unit auto get-common-scaled-unit(U1, U2, Rest... rest) // exposition only + requires see below; +
    Effects: Equivalent to: +constexpr auto res = [] { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + constexpr auto common_mag = common-magnitude(canonical_lhs.mag, canonical_rhs.mag); + if constexpr (common_mag == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit<common_mag, decltype(auto(canonical_lhs.reference_unit))>{}; +}(); +if constexpr (sizeof...(rest) == 0) + return res; +else + return get-common-scaled-unit(res, rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(U1{}, U2{}) && (sizeof...(Rest) == 0 || requires { + get-common-scaled-unit(get-common-scaled-unit(u1, u2), rest...); + })) +

    5.4.4.5.6 Derived [qty.derived.unit]

    namespace mp_units { + +template<typename... Expr> +struct derived-unit-impl : // exposition only + unit-interface, + expr-fractions<struct one, Expr...> { + using base-type = derived-unit-impl; // exposition only +}; + +template<SymbolicConstant... Expr> +struct derived_unit final : derived-unit-impl<Expr...> {}; + +} +
    derived_unit is used by the library +to represent a derived unit (IEC 60050, 112-01-19).
    [Example 1: using namespace si::unit_symbols; +int x = m * m; // error: cannot construct from derived_unit<power<si​::​metre, 2>> +int y = m * s; // error: cannot construct from derived_unit<si​::​metre, si​::​second> +int z = m / s; // error: cannot construct from derived_unit<si​::​metre, per<si​::​second>> + — end example]
    +A program that instantiates a specialization of derived_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.

    5.4.4.5.7 One [qty.unit.one]

    namespace mp_units { + +struct one final : derived-unit-impl<> {}; + +} +
    one represents the base unit (IEC 60050, 112-01-18) of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.4.6 Operations [qty.unit.ops]

    namespace mp_units { + +struct unit-interface { // exposition only + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator*(M, U u); + + friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; + + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator/(M mag, U u); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); + + // [qty.unit.cmp], comparison + + template<Unit Lhs, Unit Rhs> + friend consteval bool operator==(Lhs, Rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval bool equivalent(Lhs lhs, Rhs rhs); +}; + +} +
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator*(M, U u); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<M, decltype(auto(mag<1>))>) + return u; +else if constexpr (is-specialization-of<U, scaled_unit>()) { + if constexpr (M{} * U::mag == mag<1>) + return U::reference-unit; + else + return scaled_unit<M{} * U::mag, decltype(auto(U::reference-unit))>{}; +} else + return scaled_unit<M{}, U>{}; +
    friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; +
    Recommended practice: Suggest swapping the operands.
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator/(M mag, U u); +
    Returns: mag * inverse(u).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); +
    Returns: expr-multiply<derived_unit, struct one>(lhs, rhs).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); +
    Returns: expr-divide<derived_unit, struct one>(lhs, rhs).
    consteval Unit auto inverse(Unit auto u); +
    Returns: one / u.
    template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires(Den != 0) +consteval Unit auto pow(U u); +
    Returns: expr-pow<Num, Den, derived_unit, struct one>(u).
    consteval Unit auto sqrt(Unit auto u); +
    Returns: pow<1, 2>(u).
    consteval Unit auto cbrt(Unit auto u); +
    Returns: pow<1, 3>(u).
    consteval Unit auto square(Unit auto u); +
    Returns: pow<2>(u).
    consteval Unit auto cubic(Unit auto u); +
    Returns: pow<3>(u).

    5.4.4.7 Comparison [qty.unit.cmp]

    template<Unit Lhs, Unit Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    template<Unit Lhs, Unit Rhs> +friend consteval bool equivalent(Lhs lhs, Rhs rhs); +
    Effects: Equivalent to: +const auto lhs_canonical = get-canonical-unit(lhs); +const auto rhs_canonical = get-canonical-unit(rhs); +return lhs_canonical.mag == rhs_canonical.mag && + lhs_canonical.reference_unit == rhs_canonical.reference_unit; +
    template<Unit From, Unit To> +consteval bool convertible(From from, To to); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<From, To>) + return true; +else if constexpr (PotentiallyConvertibleTo<From, To>) + return std::is_same_v<decltype(get-canonical-unit(from).reference_unit), + decltype(get-canonical-unit(to).reference_unit)>; +else + return false; +

    5.4.4.8 Observers [qty.unit.obs]

    consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +
    Returns: kind_of<get-associated-quantity(u)>.
    consteval Unit auto get_unit(AssociatedUnit auto u); +
    Returns: u.
    consteval Unit auto get_common_unit(Unit auto... us) + requires see below; +
    Let +
    • u1 be us...[0],
    • u2 be us...[1],
    • U1 be decltype(u1),
    • U2 be decltype(u2), and
    • rest be a pack denoting the elements of us without u1 and u2.
    Effects: Equivalent to: +if constexpr (sizeof...(us) == 1) + return u1; +else if constexpr (sizeof...(us) == 2) { + if constexpr (is-derived-from-specialization-of<U1, common_unit>()) { + return TBD.; + } else if constexpr (is-derived-from-specialization-of<U2, common_unit>()) + return get_common_unit(u2, u1); + else if constexpr (std::is_same_v<U1, U2>) + return u1; + else if constexpr (equivalent(U1{}, U2{})) { + if constexpr (std::derived_from<U1, typename U2::base-type>) + return u1; + else if constexpr (std::derived_from<U2, typename U1::base-type>) + return u2; + else + return std::conditional_t<type-less-impl<U1, U2>(), U1, U2>{}; + } else { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + + if constexpr (is-positive-integral-power(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is-positive-integral-power(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + if constexpr (type-less<U1, U2>{}) + return common_unit<U1, U2>{}; + else + return common_unit<U2, U1>{}; + } + } +} else + return get_common_unit(get_common_unit(u1, u2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(us) != 0 && (sizeof...(us) == 1 || // + (sizeof...(us) == 2 && convertible(U1{}, U2{})) || + requires { get_common_unit(get_common_unit(u1, u2), rest...); })) +

    5.4.4.9 Associated quantity [assoc.qty]

    template<Unit U> +consteval bool has-associated-quantity(U); // exposition only +
    Returns:
    • If U​::​quantity-spec is a valid expression, +returns true.
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +has-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +let Nums and Dens +be packs denoting the template arguments of +U​::​nums and U​::​dens, respectively.
      Returns +(... && has-associated-quantity(expr-type<Nums>{})) && + (... && has-associated-quantity(expr-type<Dens>{})) +
    • Otherwise, returns false.
    template<AssociatedUnit U> +consteval auto get-associated-quantity(U u); // exposition only +
    Returns:
    • If U is of the form common_unit<Us...>, +returns +get_common_quantity_spec(get-associated-quantity(Us{})...) +
    • Otherwise, if U​::​quantity-spec is a valid expression, +returns +remove-kind(U::quantity-spec) +
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +get-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +returns +expr-map<to-quantity-spec, derived_quantity_spec, struct dimensionless>(u) + +where to-quantity-spec is defined as follows: +template<AssociatedUnit U> +using to-quantity-spec = decltype(get-associated-quantity(U{})); // exposition only +

    5.4.4.10 Symbol formatting [qty.unit.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); +
    Effects: Equivalent to: +TBD. +

    5.4.5 Concepts [qty.ref.concepts]

    template<typename T> +concept Reference = AssociatedUnit<T> || (is-specialization-of<T, reference>()); +
    A type T that satisfies Reference +represents the reference of a quantity (IEC 60050, 112-01-01).
    template<typename T, auto QS> +concept ReferenceOf = Reference<T> && QuantitySpecOf<decltype(get_quantity_spec(T{})), QS>; +

    5.4.6 Class template reference [qty.ref.syn]

    namespace mp_units { + +template<QuantitySpec auto Q, Unit auto U> +using reference-t = reference<decltype(Q), decltype(U)>; // exposition only + +template<QuantitySpec Q, Unit U> +struct reference { + // [qty.ref.ops], operations + + template<typename Q2, typename U2> + friend consteval auto operator*(reference, reference<Q2, U2>) + -> reference-t<Q{} * Q2{}, U{} * U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator*(reference, U2) + -> reference-t<Q{} * get_quantity_spec(U2{}), U{} * U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator*(U1, reference) + -> reference-t<get_quantity_spec(U1{}) * Q{}, U1{} * U{}>; + + template<typename Q2, typename U2> + friend consteval auto operator/(reference, reference<Q2, U2>) + -> reference-t<Q{} / Q2{}, U{} / U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator/(reference, U2) + -> reference-t<Q{} / get_quantity_spec(U2{}), U{} / U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator/(U1, reference) + -> reference-t<get_quantity_spec(U1{}) / Q{}, U1{} / U{}>; + + friend consteval auto inverse(reference) -> reference-t<inverse(Q{}), inverse(U{})>; + + template<std::intmax_t Num, std::intmax_t Den = 1> + requires(Den != 0) + friend consteval auto pow(reference) -> reference-t<pow<Num, Den>(Q{}), pow<Num, Den>(U{})>; + friend consteval auto sqrt(reference) -> reference-t<sqrt(Q{}), sqrt(U{})>; + friend consteval auto cbrt(reference) -> reference-t<cbrt(Q{}), cbrt(U{})>; + + // [qty.ref.cmp], comparison + + template<typename Q2, typename U2> + friend consteval bool operator==(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool operator==(reference, U2 u2); + + template<typename Q2, typename U2> + friend consteval bool convertible(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool convertible(reference, U2 u2); + + template<AssociatedUnit U1> + friend consteval bool convertible(U1 u1, reference); +}; + +} +
    reference<Q, U> represents the reference of a quantity (IEC 60050, 112-01-01).
    The unit of measurement U (IEC 60050, 112-01-14) +is used to measure a value of the quantity Q (IEC 60050, 112-01-28).
    [Note 1: 
    reference is typically implicitly instantiated +when specifying that a unit measures a more specific quantity.
    [Example 1: using namespace si::unit_symbols; +auto x = 1 * m; // measures a length +auto y = 1 * isq::width[m]; // measures a width +auto z = 1 * isq::diameter[m]; // measures a diameter + — end example]
    — end note]

    5.4.7 Operations [qty.ref.ops]

    Each member function with a trailing-return-type +of -> reference-t<T...> +returns {}.
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), r};
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), inverse(R{})};
    template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); +
    Let @ be the operator.
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, Q::reference @ R{}}; +
    template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; +
    Recommended practice: Suggest swapping the operands.

    5.4.8 Comparison [qty.ref.cmp]

    template<typename Q2, typename U2> +friend consteval bool operator==(reference, reference<Q2, U2>); +
    Returns: Q{} == Q2{} && U{} == U2{}.
    template<AssociatedUnit U2> +friend consteval bool operator==(reference, U2 u2); +
    Returns: Q{} == get_quantity_spec(u2) && U{} == u2.
    template<typename Q2, typename U2> +friend consteval bool convertible(reference, reference<Q2, U2>); +
    Returns: implicitly_convertible(Q{}, Q2{}) && convertible(U{}, U2{}).
    template<AssociatedUnit U2> +friend consteval bool convertible(reference, U2 u2); +
    Returns: implicitly_convertible(Q{}, get_quantity_spec(u2)) && convertible(U{}, u2).
    template<AssociatedUnit U1> +friend consteval bool convertible(U1 u1, reference); +
    Returns: implicitly_convertible(get_quantity_spec(u1), Q{}) && convertible(u1, U{}).

    5.4.9 Observers [qty.ref.obs]

    template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); +
    Returns: Q{}.
    template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); +
    Returns: U{}.
    consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; +
    Returns: get_common_unit(u1, u2, rest...).
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), + get_quantity_spec(rest)...); + { get_common_unit(u1, u2, rest...) } -> AssociatedUnit; +} +
    template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; +
    Returns: reference-t<get_common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}), + get_quantity_spec(rest)...), + get_common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), + get_quantity_spec(rest)...); + get_common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...); +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.obs.html b/HEAD/api_reference/gen/qty.ref.obs.html new file mode 100644 index 00000000..920be0ca --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.obs.html @@ -0,0 +1,27 @@ +[qty.ref.obs]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.9 Observers [qty.ref.obs]

    template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); +
    Returns: Q{}.
    template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); +
    Returns: U{}.
    consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; +
    Returns: get_common_unit(u1, u2, rest...).
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), + get_quantity_spec(rest)...); + { get_common_unit(u1, u2, rest...) } -> AssociatedUnit; +} +
    template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; +
    Returns: reference-t<get_common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}), + get_quantity_spec(rest)...), + get_common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), + get_quantity_spec(rest)...); + get_common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...); +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.ops.html b/HEAD/api_reference/gen/qty.ref.ops.html new file mode 100644 index 00000000..944e98da --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.ops.html @@ -0,0 +1,34 @@ +[qty.ref.ops]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.7 Operations [qty.ref.ops]

    Each member function with a trailing-return-type +of -> reference-t<T...> +returns {}.
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), r};
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), inverse(R{})};
    template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); +
    Let @ be the operator.
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, Q::reference @ R{}}; +
    template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; +
    Recommended practice: Suggest swapping the operands.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.ref.syn.html b/HEAD/api_reference/gen/qty.ref.syn.html new file mode 100644 index 00000000..07714021 --- /dev/null +++ b/HEAD/api_reference/gen/qty.ref.syn.html @@ -0,0 +1,67 @@ +[qty.ref.syn]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.6 Class template reference [qty.ref.syn]

    namespace mp_units { + +template<QuantitySpec auto Q, Unit auto U> +using reference-t = reference<decltype(Q), decltype(U)>; // exposition only + +template<QuantitySpec Q, Unit U> +struct reference { + // [qty.ref.ops], operations + + template<typename Q2, typename U2> + friend consteval auto operator*(reference, reference<Q2, U2>) + -> reference-t<Q{} * Q2{}, U{} * U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator*(reference, U2) + -> reference-t<Q{} * get_quantity_spec(U2{}), U{} * U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator*(U1, reference) + -> reference-t<get_quantity_spec(U1{}) * Q{}, U1{} * U{}>; + + template<typename Q2, typename U2> + friend consteval auto operator/(reference, reference<Q2, U2>) + -> reference-t<Q{} / Q2{}, U{} / U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator/(reference, U2) + -> reference-t<Q{} / get_quantity_spec(U2{}), U{} / U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator/(U1, reference) + -> reference-t<get_quantity_spec(U1{}) / Q{}, U1{} / U{}>; + + friend consteval auto inverse(reference) -> reference-t<inverse(Q{}), inverse(U{})>; + + template<std::intmax_t Num, std::intmax_t Den = 1> + requires(Den != 0) + friend consteval auto pow(reference) -> reference-t<pow<Num, Den>(Q{}), pow<Num, Den>(U{})>; + friend consteval auto sqrt(reference) -> reference-t<sqrt(Q{}), sqrt(U{})>; + friend consteval auto cbrt(reference) -> reference-t<cbrt(Q{}), cbrt(U{})>; + + // [qty.ref.cmp], comparison + + template<typename Q2, typename U2> + friend consteval bool operator==(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool operator==(reference, U2 u2); + + template<typename Q2, typename U2> + friend consteval bool convertible(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool convertible(reference, U2 u2); + + template<AssociatedUnit U1> + friend consteval bool convertible(U1 u1, reference); +}; + +} +
    reference<Q, U> represents the reference of a quantity (IEC 60050, 112-01-01).
    The unit of measurement U (IEC 60050, 112-01-14) +is used to measure a value of the quantity Q (IEC 60050, 112-01-28).
    [Note 1: 
    reference is typically implicitly instantiated +when specifying that a unit measures a more specific quantity.
    [Example 1: using namespace si::unit_symbols; +auto x = 1 * m; // measures a length +auto y = 1 * isq::width[m]; // measures a width +auto z = 1 * isq::diameter[m]; // measures a diameter + — end example]
    — end note]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rel.pt.orig.html b/HEAD/api_reference/gen/qty.rel.pt.orig.html new file mode 100644 index 00000000..c9b7288a --- /dev/null +++ b/HEAD/api_reference/gen/qty.rel.pt.orig.html @@ -0,0 +1,18 @@ +[qty.rel.pt.orig]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.2 Relative [qty.rel.pt.orig]

    namespace mp_units { + +template<QuantityPoint auto QP> +struct relative_point_origin : point-origin-interface { + static constexpr QuantityPoint auto quantity-point = QP; // exposition only + static constexpr QuantitySpec auto quantity-spec = see below; // exposition only + static constexpr PointOrigin auto absolute-point-origin = // exposition only + QP.absolute_point_origin; +}; + +} +
    A relative origin is an origin +of a subspace (IEC 60050, 102-03-03).
    A specialization of relative_point_origin is used as a base type when defining a relative origin O.
    O is offset from QP.absolute_point_origin by QP.quantity_from_zero().
    The member quantity-spec is equal to +QP.point_origin.quantity-spec if +QuantityKindSpec<decltype(auto(QP.quantity-spec))> + +is satisfied, and +to QP.quantity-spec otherwise.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rep.concepts.html b/HEAD/api_reference/gen/qty.rep.concepts.html new file mode 100644 index 00000000..9029baf4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.rep.concepts.html @@ -0,0 +1,88 @@ +[qty.rep.concepts]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.4 Concepts [qty.rep.concepts]

    template<typename T> +concept WeaklyRegular = std::copyable<T> && std::equality_comparable<T>; // exposition only + +template<typename T> +concept Scalar = (!disable_scalar<T>) && WeaklyRegular<T> && requires(T a, T b) { // exposition only + // 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>; +}; +
    TBD.
    template<typename T> +using value-type-t = actual-value-type-t<T>; // exposition only, see [qty.fp.traits] + +template<typename T> +concept Complex = // exposition only + (!disable_complex<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + std::constructible_from<T, value-type-t<T>, value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +concept Vector = // exposition only + (!disable_vector<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +using scaling-factor-type-t = // exposition only + std::conditional_t<treat_as_floating_point<T>, long double, std::intmax_t>; + +template<typename T> +concept ScalarRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Scalar<T> && + requires(T a, T b, 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>; + }; +
    TBD.
    template<typename T> +concept ComplexRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Complex<T> && + requires(T a, T b, scaling-factor-type-t<T> f) { + // scaling + { a * T(f) } -> std::common_with<T>; + { T(f) * a } -> std::common_with<T>; + { a / T(f) } -> std::common_with<T>; + }; +
    TBD.
    template<typename T> +concept VectorRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Vector<T>; +
    TBD.
    template<typename T> +concept Representation = ScalarRepresentation<T> || ComplexRepresentation<T> || + VectorRepresentation<T>; +
    A type T models Representation if +it represents the numerical value of a quantity (IEC 60050, 112-01-29).
    template<typename T, quantity_character Ch> +concept IsOfCharacter = (Ch == quantity_character::scalar && Scalar<T>) || // exposition only + (Ch == quantity_character::complex && Complex<T>) || + (Ch == quantity_character::vector && Vector<T>); + +template<typename T, auto V> +concept RepresentationOf = + Representation<T> && ((QuantitySpec<decltype(V)> && + (QuantityKindSpec<decltype(V)> || IsOfCharacter<T, V.character>)) || + (std::same_as<quantity_character, decltype(V)> && IsOfCharacter<T, V>)); +
    A type T models RepresentationOf<V> if +T models Representation and +
    • V is a kind of quantity, or
    • if V is a quantity, then T represents a value of its character, or
    • if V is a quantity character, then T represents a value of V.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rep.cpos.general.html b/HEAD/api_reference/gen/qty.rep.cpos.general.html new file mode 100644 index 00000000..444fccbd --- /dev/null +++ b/HEAD/api_reference/gen/qty.rep.cpos.general.html @@ -0,0 +1,2 @@ +[qty.rep.cpos.general]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.1 General [qty.rep.cpos.general]

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rep.cpos.html b/HEAD/api_reference/gen/qty.rep.cpos.html new file mode 100644 index 00000000..980fa0a4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.rep.cpos.html @@ -0,0 +1,38 @@ +[qty.rep.cpos]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.1 General [qty.rep.cpos.general]

    Within subclause [qty.rep.cpos], +reified object is as defined in N4971, [range.access.general].

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    The name mp_units​::​real denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​real(E) is ill-formed.
    • If auto(t.real()) is a valid expression whose type models Scalar, +mp_units​::​real(E) is expression-equivalent to auto(t.real()).
    • Otherwise, if T is a class or enumeration type and +auto(real(t)) is a valid expression whose type models Scalar +where the meaning of real is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​real(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​real(E) is ill-formed.

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    The name mp_units​::​imag denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​imag(E) is ill-formed.
    • If auto(t.imag()) is a valid expression whose type models Scalar, +mp_units​::​imag(E) is expression-equivalent to auto(t.imag()).
    • Otherwise, if T is a class or enumeration type and +auto(imag(t)) is a valid expression whose type models Scalar +where the meaning of imag is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​imag(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​imag(E) is ill-formed.

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    The name mp_units​::​modulus denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​modulus(E) is ill-formed.
    • If auto(t.modulus()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.modulus()).
    • Otherwise, if T is a class or enumeration type and +auto(modulus(t)) is a valid expression whose type models Scalar +where the meaning of modulus is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • If auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of abs is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​modulus(E) is ill-formed.

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    The name mp_units​::​magnitude denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​magnitude(E) is ill-formed.
    • If auto(t.magnitude()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(E) is expression-equivalent to auto(t.magnitude()).
    • Otherwise, if T is a class or enumeration type and +auto(magnitude(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, if auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(​E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​magnitude(E) is ill-formed.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rep.general.html b/HEAD/api_reference/gen/qty.rep.general.html new file mode 100644 index 00000000..a087eebf --- /dev/null +++ b/HEAD/api_reference/gen/qty.rep.general.html @@ -0,0 +1,2 @@ +[qty.rep.general]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.1 General [qty.rep.general]

    Subclause [qty.rep] specifies the components +used to constrain the numerical value of a quantity (IEC 60050, 112-01-29).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rep.html b/HEAD/api_reference/gen/qty.rep.html new file mode 100644 index 00000000..b3de5030 --- /dev/null +++ b/HEAD/api_reference/gen/qty.rep.html @@ -0,0 +1,166 @@ +[qty.rep]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.1 General [qty.rep.general]

    Subclause [qty.rep] specifies the components +used to constrain the numerical value of a quantity (IEC 60050, 112-01-29).

    5.5.2 Traits [qty.rep.traits]

    5.5.2.1 Floating-point [qty.fp.traits]

    template<typename T> +struct actual-value-type : cond-value-type<T> {}; // see N4971, [readable.traits] + +template<typename T> + requires(!std::is_pointer_v<T> && !std::is_array_v<T>) && + requires { typename std::indirectly_readable_traits<T>::value_type; } +struct actual-value-type<T> : std::indirectly_readable_traits<T> {}; + +template<typename T> +using actual-value-type-t = actual-value-type<T>::value_type; + +template<typename Rep> +constexpr bool treat_as_floating_point = + std::chrono::treat_as_floating_point_v<actual-value-type-t<Rep>>; +
    quantity and quantity_point use treat_as_floating_point +to help determine whether implicit conversions are allowed among them.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize treat_as_floating_point +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.5.2.2 Quantity character [qty.char.traits]

    template<typename T> +constexpr bool disable_scalar = false; +template<typename T> +constexpr bool disable_complex = false; +template<typename T> +constexpr bool disable_vector = false; +
    Some quantities are defined as having a numerical value (IEC 60050, 112-01-29) of a specific set (IEC 60050, 102-01-02).
    The representation concepts use these traits +to help determine the sets T represents.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize these templates +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    [Note 1: 
    These templates prevent use of representation types with the library +that satisfy but do not in fact model their corresponding concept.
    — end note]

    5.5.2.3 Values [qty.val.traits]

    quantity and quantity_point use representation_values +to construct special values of its representation type.
    namespace mp_units { + +template<typename Rep> +struct representation_values : std::chrono::duration_values<Rep> { + static constexpr Rep one() noexcept; +}; + +} +
    The requirements on std​::​chrono​::​duration_values<Rep> (N4971, [time.traits.duration.values]) +also apply to representation_values<Rep>.
    static constexpr Rep one() noexcept; +
    Returns: Rep(1).
    Remarks: The value returned shall be the neutral element for multiplication (IEC 60050, 102-01-19).

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    The name mp_units​::​real denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​real(E) is ill-formed.
    • If auto(t.real()) is a valid expression whose type models Scalar, +mp_units​::​real(E) is expression-equivalent to auto(t.real()).
    • Otherwise, if T is a class or enumeration type and +auto(real(t)) is a valid expression whose type models Scalar +where the meaning of real is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​real(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​real(E) is ill-formed.

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    The name mp_units​::​imag denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​imag(E) is ill-formed.
    • If auto(t.imag()) is a valid expression whose type models Scalar, +mp_units​::​imag(E) is expression-equivalent to auto(t.imag()).
    • Otherwise, if T is a class or enumeration type and +auto(imag(t)) is a valid expression whose type models Scalar +where the meaning of imag is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​imag(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​imag(E) is ill-formed.

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    The name mp_units​::​modulus denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​modulus(E) is ill-formed.
    • If auto(t.modulus()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.modulus()).
    • Otherwise, if T is a class or enumeration type and +auto(modulus(t)) is a valid expression whose type models Scalar +where the meaning of modulus is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • If auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of abs is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​modulus(E) is ill-formed.

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    The name mp_units​::​magnitude denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​magnitude(E) is ill-formed.
    • If auto(t.magnitude()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(E) is expression-equivalent to auto(t.magnitude()).
    • Otherwise, if T is a class or enumeration type and +auto(magnitude(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, if auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(​E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​magnitude(E) is ill-formed.

    5.5.4 Concepts [qty.rep.concepts]

    template<typename T> +concept WeaklyRegular = std::copyable<T> && std::equality_comparable<T>; // exposition only + +template<typename T> +concept Scalar = (!disable_scalar<T>) && WeaklyRegular<T> && requires(T a, T b) { // exposition only + // 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>; +}; +
    TBD.
    template<typename T> +using value-type-t = actual-value-type-t<T>; // exposition only, see [qty.fp.traits] + +template<typename T> +concept Complex = // exposition only + (!disable_complex<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + std::constructible_from<T, value-type-t<T>, value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +concept Vector = // exposition only + (!disable_vector<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +using scaling-factor-type-t = // exposition only + std::conditional_t<treat_as_floating_point<T>, long double, std::intmax_t>; + +template<typename T> +concept ScalarRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Scalar<T> && + requires(T a, T b, 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>; + }; +
    TBD.
    template<typename T> +concept ComplexRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Complex<T> && + requires(T a, T b, scaling-factor-type-t<T> f) { + // scaling + { a * T(f) } -> std::common_with<T>; + { T(f) * a } -> std::common_with<T>; + { a / T(f) } -> std::common_with<T>; + }; +
    TBD.
    template<typename T> +concept VectorRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Vector<T>; +
    TBD.
    template<typename T> +concept Representation = ScalarRepresentation<T> || ComplexRepresentation<T> || + VectorRepresentation<T>; +
    A type T models Representation if +it represents the numerical value of a quantity (IEC 60050, 112-01-29).
    template<typename T, quantity_character Ch> +concept IsOfCharacter = (Ch == quantity_character::scalar && Scalar<T>) || // exposition only + (Ch == quantity_character::complex && Complex<T>) || + (Ch == quantity_character::vector && Vector<T>); + +template<typename T, auto V> +concept RepresentationOf = + Representation<T> && ((QuantitySpec<decltype(V)> && + (QuantityKindSpec<decltype(V)> || IsOfCharacter<T, V.character>)) || + (std::same_as<quantity_character, decltype(V)> && IsOfCharacter<T, V>)); +
    A type T models RepresentationOf<V> if +T models Representation and +
    • V is a kind of quantity, or
    • if V is a quantity, then T represents a value of its character, or
    • if V is a quantity character, then T represents a value of V.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.rep.traits.html b/HEAD/api_reference/gen/qty.rep.traits.html new file mode 100644 index 00000000..f95655dc --- /dev/null +++ b/HEAD/api_reference/gen/qty.rep.traits.html @@ -0,0 +1,41 @@ +[qty.rep.traits]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.2 Traits [qty.rep.traits]

    5.5.2.1 Floating-point [qty.fp.traits]

    template<typename T> +struct actual-value-type : cond-value-type<T> {}; // see N4971, [readable.traits] + +template<typename T> + requires(!std::is_pointer_v<T> && !std::is_array_v<T>) && + requires { typename std::indirectly_readable_traits<T>::value_type; } +struct actual-value-type<T> : std::indirectly_readable_traits<T> {}; + +template<typename T> +using actual-value-type-t = actual-value-type<T>::value_type; + +template<typename Rep> +constexpr bool treat_as_floating_point = + std::chrono::treat_as_floating_point_v<actual-value-type-t<Rep>>; +
    quantity and quantity_point use treat_as_floating_point +to help determine whether implicit conversions are allowed among them.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize treat_as_floating_point +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.5.2.2 Quantity character [qty.char.traits]

    template<typename T> +constexpr bool disable_scalar = false; +template<typename T> +constexpr bool disable_complex = false; +template<typename T> +constexpr bool disable_vector = false; +
    Some quantities are defined as having a numerical value (IEC 60050, 112-01-29) of a specific set (IEC 60050, 102-01-02).
    The representation concepts use these traits +to help determine the sets T represents.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize these templates +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    [Note 1: 
    These templates prevent use of representation types with the library +that satisfy but do not in fact model their corresponding concept.
    — end note]

    5.5.2.3 Values [qty.val.traits]

    quantity and quantity_point use representation_values +to construct special values of its representation type.
    namespace mp_units { + +template<typename Rep> +struct representation_values : std::chrono::duration_values<Rep> { + static constexpr Rep one() noexcept; +}; + +} +
    The requirements on std​::​chrono​::​duration_values<Rep> (N4971, [time.traits.duration.values]) +also apply to representation_values<Rep>.
    static constexpr Rep one() noexcept; +
    Returns: Rep(1).
    Remarks: The value returned shall be the neutral element for multiplication (IEC 60050, 102-01-19).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.same.abs.pt.origs.html b/HEAD/api_reference/gen/qty.same.abs.pt.origs.html new file mode 100644 index 00000000..03bc1fdb --- /dev/null +++ b/HEAD/api_reference/gen/qty.same.abs.pt.origs.html @@ -0,0 +1,16 @@ +[qty.same.abs.pt.origs]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.1 Same absolute [qty.same.abs.pt.origs]

    template<PointOrigin PO1, PointOrigin PO2> +consteval bool same-absolute-point-origins(PO1 po1, PO2 po2); // exposition only +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return po1 == po2; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1.absolute-point-origin == po2.absolute-point-origin; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return po1.absolute-point-origin == po2; +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1 == po2.absolute-point-origin; +else + return false; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.scaled.unit.html b/HEAD/api_reference/gen/qty.scaled.unit.html new file mode 100644 index 00000000..e8fb2e9e --- /dev/null +++ b/HEAD/api_reference/gen/qty.scaled.unit.html @@ -0,0 +1,15 @@ +[qty.scaled.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.2 Scaled [qty.scaled.unit]

    namespace mp_units { + +template<UnitMagnitude auto M, Unit U> + requires(M != unit-magnitude<>{} && M != mag<1>) +struct scaled_unit final : unit-interface { + using base-type = scaled_unit; // exposition only + static constexpr UnitMagnitude auto mag = M; // exposition only + static constexpr U reference-unit{}; // exposition only + static constexpr auto point-origin = U::point_origin; // exposition only, present only + // if the qualified-id U​::​point_origin is valid and denotes an object +}; + +} +
    scaled_unit<M, U> is used by the library +to represent the unit M ×U.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.concepts.html b/HEAD/api_reference/gen/qty.spec.concepts.html new file mode 100644 index 00000000..4b2a603a --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.concepts.html @@ -0,0 +1,48 @@ +[qty.spec.concepts]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.2 Concepts [qty.spec.concepts]

    template<typename T> +concept QuantitySpec = SymbolicConstant<T> && std::derived_from<T, quantity-spec-interface>; + +template<typename T> +concept QuantityKindSpec = // exposition only + QuantitySpec<T> && is-specialization-of<T, kind_of_>(); + +template<typename T> +concept NamedQuantitySpec = // exposition only + QuantitySpec<T> && is-derived-from-specialization-of<T, quantity_spec>() && + (!QuantityKindSpec<T>); + +template<typename T> +concept DerivedQuantitySpec = // exposition only + QuantitySpec<T> && + (is-specialization-of<T, derived_quantity_spec>() || + (QuantityKindSpec<T> && + is-specialization-of<decltype(auto(T::quantity-spec)), derived_quantity_spec>())); + +template<auto Child, auto Parent> +concept ChildQuantitySpecOf = (is-child-of(Child, Parent)); // exposition only + +template<auto To, auto From> +concept NestedQuantityKindSpecOf = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && + (get_kind(From) != get_kind(To)) && ChildQuantitySpecOf<To, get_kind(From).quantity-spec>; + +template<auto From, auto To> +concept QuantitySpecConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && implicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecExplicitlyConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && explicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecCastableTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && castable(From, To); + +template<typename T, auto QS> +concept QuantitySpecOf = + QuantitySpec<T> && QuantitySpec<decltype(QS)> && QuantitySpecConvertibleTo<T{}, QS> && + !NestedQuantityKindSpecOf<T{}, QS> && + (QuantityKindSpec<T> || !NestedQuantityKindSpecOf<QS, T{}>); + +template<typename T> +concept QSProperty = (!QuantitySpec<T>); // exposition only +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.conv.html b/HEAD/api_reference/gen/qty.spec.conv.html new file mode 100644 index 00000000..0839d4db --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.conv.html @@ -0,0 +1,5 @@ +[qty.spec.conv]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.1 Conversion [qty.spec.conv]

    consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); +
    Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.general.html b/HEAD/api_reference/gen/qty.spec.general.html new file mode 100644 index 00000000..d18a819a --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.general.html @@ -0,0 +1,2 @@ +[qty.spec.general]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.1 General [qty.spec.general]

    Subclause [qty.spec] specifies the components +for defining a quantity (IEC 60050, 112-01-01).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.hier.algos.html b/HEAD/api_reference/gen/qty.spec.hier.algos.html new file mode 100644 index 00000000..3baeb3a4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.hier.algos.html @@ -0,0 +1,75 @@ +[qty.spec.hier.algos]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.1 Conversion [qty.spec.conv]

    consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); +
    Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).

    5.4.3.6.2 Get kind [qty.get.kind]

    template<QuantitySpec Q> +consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only +
    Returns:
    • If QuantityKindSpec<Q> is true, +returns remove-kind(q).
    • Otherwise, if +is-derived-from-specialization-of<Q, quantity_spec>() +is true, and +the specialization of Q​::​quantity_spec has a template argument equal to is_kind, +returns q.
    • Otherwise, if Q​::​parent is a valid expression, +returns get-kind-tree-root(Q​::​parent).
    • Otherwise, if DerivedQuantitySpec<Q> is true, +returns +expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) + +where to-kind is defined as follows: +template<QuantitySpec Q> +using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only +
    • Otherwise, returns q.
    template<QuantitySpec Q> +consteval QuantityKindSpec auto get_kind(Q); +
    Returns: kind_of<get-kind-tree-root(Q{})>.

    5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

    consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; +
    Let +
    • q1 be qs...[0],
    • q2 be qs...[1],
    • Q1 be decltype(q1),
    • Q2 be decltype(q2), and
    • rest be a pack denoting the elements of qs without q1 and q2.
    Effects: Equivalent to: +if constexpr (sizeof...(qs) == 1) + return q1; +else if constexpr (sizeof...(qs) == 2) { + using QQ1 = decltype(remove-kind(q1)); + using QQ2 = decltype(remove-kind(q2)); + + if constexpr (std::is_same_v<Q1, Q2>) + return q1; + else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) + return QQ1{}; + else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) + return QQ2{}; + else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || + (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && + implicitly_convertible(Q1{}, Q2{}))) + return q2; + else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || + (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && + implicitly_convertible(Q2{}, Q1{}))) + return q1; + else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) + return *common_base; + else if constexpr (implicitly_convertible(Q1{}, Q2{})) + return q2; + else if constexpr (implicitly_convertible(Q2{}, Q1{})) + return q1; + else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), + get-kind-tree-root(Q2{}))) + return get-kind-tree-root(q2); + else + return get-kind-tree-root(q1); +} else + return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(qs) != 0 && + (sizeof...(qs) == 1 || + (sizeof...(qs) == 2 && + (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || + QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || + requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); })) +

    5.4.3.6.4 Get common base [qty.get.common.base]

    In this subclause and [qty.is.child.of], +let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple +, +where par is parent.
    template<QuantitySpec auto A, QuantitySpec auto B> +consteval auto get-common-base(); // exposition only +
    Let +
    • be the number of elements in h(A),
    • be the number of elements in h(B),
    • s be ,
    • A be a tuple of the last s elements of h(A), and
    • B be a tuple of the last s elements of h(B).
    Effects: Looks for x, the first pair-wise equal element in A and B.
    Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.

    5.4.3.6.5 Is child of [qty.is.child.of]

    template<QuantitySpec Child, QuantitySpec Parent> +consteval bool is-child-of(Child ch, Parent p); // exposition only +
    Returns: If h(p) has more elements than h(ch), returns false.
    Otherwise, let C be a tuple of the last s elements of h(ch), +where s is the number of elements in h(p).
    Returns == p.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.html b/HEAD/api_reference/gen/qty.spec.html new file mode 100644 index 00000000..27bc68e0 --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.html @@ -0,0 +1,306 @@ +[qty.spec]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.1 General [qty.spec.general]

    Subclause [qty.spec] specifies the components +for defining a quantity (IEC 60050, 112-01-01).

    5.4.3.2 Concepts [qty.spec.concepts]

    template<typename T> +concept QuantitySpec = SymbolicConstant<T> && std::derived_from<T, quantity-spec-interface>; + +template<typename T> +concept QuantityKindSpec = // exposition only + QuantitySpec<T> && is-specialization-of<T, kind_of_>(); + +template<typename T> +concept NamedQuantitySpec = // exposition only + QuantitySpec<T> && is-derived-from-specialization-of<T, quantity_spec>() && + (!QuantityKindSpec<T>); + +template<typename T> +concept DerivedQuantitySpec = // exposition only + QuantitySpec<T> && + (is-specialization-of<T, derived_quantity_spec>() || + (QuantityKindSpec<T> && + is-specialization-of<decltype(auto(T::quantity-spec)), derived_quantity_spec>())); + +template<auto Child, auto Parent> +concept ChildQuantitySpecOf = (is-child-of(Child, Parent)); // exposition only + +template<auto To, auto From> +concept NestedQuantityKindSpecOf = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && + (get_kind(From) != get_kind(To)) && ChildQuantitySpecOf<To, get_kind(From).quantity-spec>; + +template<auto From, auto To> +concept QuantitySpecConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && implicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecExplicitlyConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && explicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecCastableTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && castable(From, To); + +template<typename T, auto QS> +concept QuantitySpecOf = + QuantitySpec<T> && QuantitySpec<decltype(QS)> && QuantitySpecConvertibleTo<T{}, QS> && + !NestedQuantityKindSpecOf<T{}, QS> && + (QuantityKindSpec<T> || !NestedQuantityKindSpecOf<QS, T{}>); + +template<typename T> +concept QSProperty = (!QuantitySpec<T>); // exposition only +

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.1 Named [named.qty]

    namespace mp_units { + +struct is_kind {}; + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr BaseDimension auto dimension = Dim; + static constexpr quantity_character character = see below; +}; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = parent.equation; // exposition only, present only + // if the qualified-id parent.equation is valid and denotes an object + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> + requires QuantitySpecExplicitlyConvertibleTo<Eq, QS> +struct quantity_spec<QS, Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +} +
    A named quantity is a type that models NamedQuantitySpec.
    A specialization of quantity_spec is used as a base type when defining a named quantity.
    In the following descriptions, let Q be a named quantity defined with an alluded signature.
    The identifier of Q represents its quantity name (IEC 60050, 112-01-02).
    Let Ch be an enumerator value of quantity_character.
    The possible arguments to quantity_spec are +
    • ,
    • ,
    • , and
    • .
    If the first argument is a base quantity dimension, +then Q is that base quantity (IEC 60050, 112-01-08).
    If an argument is a quantity calculus (IEC 60050, 112-01-30) C, +then Q is implicitly convertible from C.
    If the first argument is a named quantity, +then Q is of its kind (IEC 60050, 112-01-04).
    The member character represents +the set of the numerical value of Q ([qty.char.traits]) +and is equal to +
    • Ch if specified,
    • otherwise, quantity_character​::​scalar for the first signature, and
    • otherwise, (BC).character, +where BC is the argument preceding Ch in the signatures above.
    is_kind specifies Q to start a new hierarchy tree of a kind.
    Optional arguments may appear in any order.
    [Example 1: // The first signature defines a base quantity. +inline constexpr struct length final : quantity_spec<dim_length> { +} length; // Length is a base quantity. + +// The second signature defines a derived quantity. +inline constexpr struct area final : quantity_spec<pow<2>(length)> { +} area; // An area equals length by length. + +// The third and fourth signatures add a leaf to a hierarchy of kinds. +inline constexpr struct width final : quantity_spec<length> { +} width; // Width is a kind of length. + +// The fourth signature also refines the calculus required for implicit conversions. +inline constexpr struct angular_measure final : + quantity_spec<dimensionless, arc_length / radius, is_kind> { +} angular_measure; // Requires an arc length per radius, not just any quantity of dimension one. + — end example]

    5.4.3.3.2 Derived [derived.qty]

    namespace mp_units { + +template<NamedQuantitySpec Q> +using to-dimension = decltype(auto(Q::dimension)); // exposition only + +template<typename... Expr> +struct derived-quantity-spec-impl : // exposition only + quantity-spec-interface, + expr-fractions<struct dimensionless, Expr...> { + using base-type = derived-quantity-spec-impl; + using base = expr-fractions<struct dimensionless, Expr...>; + + static constexpr Dimension auto dimension = + expr-map<to-dimension, derived_dimension, struct dimension_one>(base{}); + static constexpr quantity_character character = see below; +}; + +template<SymbolicConstant... Expr> +struct derived_quantity_spec final : derived-quantity-spec-impl<Expr...> {}; + +} +
    derived_quantity_spec is used by the library +to represent the result of a quantity calculus not equal to a named quantity.
    [Example 1: constexpr auto area = pow<2>(isq::length); +int x = area; // error: cannot construct from derived_quantity_spec<power<isq​::​length, 2>> + — end example]
    +A program that instantiates a specialization of derived_quantity_spec +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let +
    • Nums and Dens +be packs denoting the template arguments of +base​::​nums and base​::​dens, respectively,
    • QUANTITY-CHARACTER-OF(Pack) be +std::max({quantity_character::scalar, expr-type<Pack>::character...}) + +and
    • num_char be QUANTITY-CHARACTER-OF(Nums) and +den_char be QUANTITY-CHARACTER-OF(Dens).
    +The member character is equal to +quantity_character​::​scalar if num_char == den_char is true, and +std​::​max(num_char, den_char) otherwise.

    5.4.3.3.3 Base quantity of dimension one [dimless.qty]

    namespace mp_units { + +struct dimensionless final : quantity_spec<derived_quantity_spec<>> {}; + +} +
    dimensionless represents the base quantity of dimension one (IEC 60050, 112-01-13).

    5.4.3.3.4 Kind of [kind.of.qty]

    namespace mp_units { + +template<QuantitySpec Q> + requires(!QuantityKindSpec<Q>) && (get-kind-tree-root(Q{}) == Q{}) +struct kind_of_ final : Q::base-type { + using base-type = kind_of_; // exposition only + static constexpr auto quantity-spec = Q{}; // exposition only +}; + +} +
    kind_of<Q> represents a kind of quantity (IEC 60050, 112-01-04) Q.

    5.4.3.4 Utilities [qty.spec.utils]

    template<QuantitySpec auto... From, QuantitySpec Q> +consteval QuantitySpec auto clone-kind-of(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr ((... && QuantityKindSpec<decltype(From)>)) + return kind_of<Q{}>; +else + return q; +
    template<QuantitySpec Q> +consteval auto remove-kind(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr (QuantityKindSpec<Q>) + return Q::quantity-spec; +else + return q; +
    template<QuantitySpec QS, Unit U> + requires(!AssociatedUnit<U>) || UnitOf<U, QS{}> +consteval Reference auto make-reference(QS, U u); // exposition only +
    Effects: Equivalent to: +if constexpr (requires { requires get_quantity_spec(U{}) == QS{}; }) + return u; +else + return reference<QS, U>{}; +

    5.4.3.5 Operations [qty.spec.ops]

    namespace mp_units { + +struct quantity-spec-interface { // exposition only + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); + + template<typename Self, UnitOf<Self{}> U> + consteval Reference auto operator[](this Self self, U u); + + template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> + constexpr Quantity auto operator()(this Self self, FwdQ&& q); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-multiply<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-divide<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<typename Self, UnitOf<Self{}> U> +consteval Reference auto operator[](this Self self, U u); +
    Returns: make-reference(self, u).
    template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> +constexpr Quantity auto operator()(this Self self, FwdQ&& q); +
    Returns: quantity{std::forward<FwdQ>(q).numerical-value, make-reference(self, Q::unit)} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval QuantitySpec auto inverse(QuantitySpec auto q); +
    Returns: dimensionless / q.
    template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +
    Returns: clone-kind-of<Q{}>( + expr-pow<Num, Den, derived_quantity_spec, struct dimensionless>(remove-kind(q))); +
    consteval QuantitySpec auto sqrt(QuantitySpec auto q); +
    Returns: pow<1, 2>(q).
    consteval QuantitySpec auto cbrt(QuantitySpec auto q); +
    Returns: pow<1, 3>(q).

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.1 Conversion [qty.spec.conv]

    consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); +
    Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).

    5.4.3.6.2 Get kind [qty.get.kind]

    template<QuantitySpec Q> +consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only +
    Returns:
    • If QuantityKindSpec<Q> is true, +returns remove-kind(q).
    • Otherwise, if +is-derived-from-specialization-of<Q, quantity_spec>() +is true, and +the specialization of Q​::​quantity_spec has a template argument equal to is_kind, +returns q.
    • Otherwise, if Q​::​parent is a valid expression, +returns get-kind-tree-root(Q​::​parent).
    • Otherwise, if DerivedQuantitySpec<Q> is true, +returns +expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) + +where to-kind is defined as follows: +template<QuantitySpec Q> +using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only +
    • Otherwise, returns q.
    template<QuantitySpec Q> +consteval QuantityKindSpec auto get_kind(Q); +
    Returns: kind_of<get-kind-tree-root(Q{})>.

    5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

    consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; +
    Let +
    • q1 be qs...[0],
    • q2 be qs...[1],
    • Q1 be decltype(q1),
    • Q2 be decltype(q2), and
    • rest be a pack denoting the elements of qs without q1 and q2.
    Effects: Equivalent to: +if constexpr (sizeof...(qs) == 1) + return q1; +else if constexpr (sizeof...(qs) == 2) { + using QQ1 = decltype(remove-kind(q1)); + using QQ2 = decltype(remove-kind(q2)); + + if constexpr (std::is_same_v<Q1, Q2>) + return q1; + else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) + return QQ1{}; + else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) + return QQ2{}; + else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || + (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && + implicitly_convertible(Q1{}, Q2{}))) + return q2; + else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || + (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && + implicitly_convertible(Q2{}, Q1{}))) + return q1; + else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) + return *common_base; + else if constexpr (implicitly_convertible(Q1{}, Q2{})) + return q2; + else if constexpr (implicitly_convertible(Q2{}, Q1{})) + return q1; + else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), + get-kind-tree-root(Q2{}))) + return get-kind-tree-root(q2); + else + return get-kind-tree-root(q1); +} else + return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(qs) != 0 && + (sizeof...(qs) == 1 || + (sizeof...(qs) == 2 && + (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || + QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || + requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); })) +

    5.4.3.6.4 Get common base [qty.get.common.base]

    In this subclause and [qty.is.child.of], +let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple +, +where par is parent.
    template<QuantitySpec auto A, QuantitySpec auto B> +consteval auto get-common-base(); // exposition only +
    Let +
    • be the number of elements in h(A),
    • be the number of elements in h(B),
    • s be ,
    • A be a tuple of the last s elements of h(A), and
    • B be a tuple of the last s elements of h(B).
    Effects: Looks for x, the first pair-wise equal element in A and B.
    Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.

    5.4.3.6.5 Is child of [qty.is.child.of]

    template<QuantitySpec Child, QuantitySpec Parent> +consteval bool is-child-of(Child ch, Parent p); // exposition only +
    Returns: If h(p) has more elements than h(ch), returns false.
    Otherwise, let C be a tuple of the last s elements of h(ch), +where s is the number of elements in h(p).
    Returns == p.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.ops.html b/HEAD/api_reference/gen/qty.spec.ops.html new file mode 100644 index 00000000..58a64e5b --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.ops.html @@ -0,0 +1,46 @@ +[qty.spec.ops]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.5 Operations [qty.spec.ops]

    namespace mp_units { + +struct quantity-spec-interface { // exposition only + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); + + template<typename Self, UnitOf<Self{}> U> + consteval Reference auto operator[](this Self self, U u); + + template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> + constexpr Quantity auto operator()(this Self self, FwdQ&& q); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-multiply<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-divide<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<typename Self, UnitOf<Self{}> U> +consteval Reference auto operator[](this Self self, U u); +
    Returns: make-reference(self, u).
    template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> +constexpr Quantity auto operator()(this Self self, FwdQ&& q); +
    Returns: quantity{std::forward<FwdQ>(q).numerical-value, make-reference(self, Q::unit)} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval QuantitySpec auto inverse(QuantitySpec auto q); +
    Returns: dimensionless / q.
    template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +
    Returns: clone-kind-of<Q{}>( + expr-pow<Num, Den, derived_quantity_spec, struct dimensionless>(remove-kind(q))); +
    consteval QuantitySpec auto sqrt(QuantitySpec auto q); +
    Returns: pow<1, 2>(q).
    consteval QuantitySpec auto cbrt(QuantitySpec auto q); +
    Returns: pow<1, 3>(q).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.types.html b/HEAD/api_reference/gen/qty.spec.types.html new file mode 100644 index 00000000..dd501f22 --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.types.html @@ -0,0 +1,117 @@ +[qty.spec.types]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.1 Named [named.qty]

    namespace mp_units { + +struct is_kind {}; + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr BaseDimension auto dimension = Dim; + static constexpr quantity_character character = see below; +}; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = parent.equation; // exposition only, present only + // if the qualified-id parent.equation is valid and denotes an object + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> + requires QuantitySpecExplicitlyConvertibleTo<Eq, QS> +struct quantity_spec<QS, Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +} +
    A named quantity is a type that models NamedQuantitySpec.
    A specialization of quantity_spec is used as a base type when defining a named quantity.
    In the following descriptions, let Q be a named quantity defined with an alluded signature.
    The identifier of Q represents its quantity name (IEC 60050, 112-01-02).
    Let Ch be an enumerator value of quantity_character.
    The possible arguments to quantity_spec are +
    • ,
    • ,
    • , and
    • .
    If the first argument is a base quantity dimension, +then Q is that base quantity (IEC 60050, 112-01-08).
    If an argument is a quantity calculus (IEC 60050, 112-01-30) C, +then Q is implicitly convertible from C.
    If the first argument is a named quantity, +then Q is of its kind (IEC 60050, 112-01-04).
    The member character represents +the set of the numerical value of Q ([qty.char.traits]) +and is equal to +
    • Ch if specified,
    • otherwise, quantity_character​::​scalar for the first signature, and
    • otherwise, (BC).character, +where BC is the argument preceding Ch in the signatures above.
    is_kind specifies Q to start a new hierarchy tree of a kind.
    Optional arguments may appear in any order.
    [Example 1: // The first signature defines a base quantity. +inline constexpr struct length final : quantity_spec<dim_length> { +} length; // Length is a base quantity. + +// The second signature defines a derived quantity. +inline constexpr struct area final : quantity_spec<pow<2>(length)> { +} area; // An area equals length by length. + +// The third and fourth signatures add a leaf to a hierarchy of kinds. +inline constexpr struct width final : quantity_spec<length> { +} width; // Width is a kind of length. + +// The fourth signature also refines the calculus required for implicit conversions. +inline constexpr struct angular_measure final : + quantity_spec<dimensionless, arc_length / radius, is_kind> { +} angular_measure; // Requires an arc length per radius, not just any quantity of dimension one. + — end example]

    5.4.3.3.2 Derived [derived.qty]

    namespace mp_units { + +template<NamedQuantitySpec Q> +using to-dimension = decltype(auto(Q::dimension)); // exposition only + +template<typename... Expr> +struct derived-quantity-spec-impl : // exposition only + quantity-spec-interface, + expr-fractions<struct dimensionless, Expr...> { + using base-type = derived-quantity-spec-impl; + using base = expr-fractions<struct dimensionless, Expr...>; + + static constexpr Dimension auto dimension = + expr-map<to-dimension, derived_dimension, struct dimension_one>(base{}); + static constexpr quantity_character character = see below; +}; + +template<SymbolicConstant... Expr> +struct derived_quantity_spec final : derived-quantity-spec-impl<Expr...> {}; + +} +
    derived_quantity_spec is used by the library +to represent the result of a quantity calculus not equal to a named quantity.
    [Example 1: constexpr auto area = pow<2>(isq::length); +int x = area; // error: cannot construct from derived_quantity_spec<power<isq​::​length, 2>> + — end example]
    +A program that instantiates a specialization of derived_quantity_spec +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let +
    • Nums and Dens +be packs denoting the template arguments of +base​::​nums and base​::​dens, respectively,
    • QUANTITY-CHARACTER-OF(Pack) be +std::max({quantity_character::scalar, expr-type<Pack>::character...}) + +and
    • num_char be QUANTITY-CHARACTER-OF(Nums) and +den_char be QUANTITY-CHARACTER-OF(Dens).
    +The member character is equal to +quantity_character​::​scalar if num_char == den_char is true, and +std​::​max(num_char, den_char) otherwise.

    5.4.3.3.3 Base quantity of dimension one [dimless.qty]

    namespace mp_units { + +struct dimensionless final : quantity_spec<derived_quantity_spec<>> {}; + +} +
    dimensionless represents the base quantity of dimension one (IEC 60050, 112-01-13).

    5.4.3.3.4 Kind of [kind.of.qty]

    namespace mp_units { + +template<QuantitySpec Q> + requires(!QuantityKindSpec<Q>) && (get-kind-tree-root(Q{}) == Q{}) +struct kind_of_ final : Q::base-type { + using base-type = kind_of_; // exposition only + static constexpr auto quantity-spec = Q{}; // exposition only +}; + +} +
    kind_of<Q> represents a kind of quantity (IEC 60050, 112-01-04) Q.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.spec.utils.html b/HEAD/api_reference/gen/qty.spec.utils.html new file mode 100644 index 00000000..e889316e --- /dev/null +++ b/HEAD/api_reference/gen/qty.spec.utils.html @@ -0,0 +1,23 @@ +[qty.spec.utils]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.3 Quantity specification [qty.spec]

    5.4.3.4 Utilities [qty.spec.utils]

    template<QuantitySpec auto... From, QuantitySpec Q> +consteval QuantitySpec auto clone-kind-of(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr ((... && QuantityKindSpec<decltype(From)>)) + return kind_of<Q{}>; +else + return q; +
    template<QuantitySpec Q> +consteval auto remove-kind(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr (QuantityKindSpec<Q>) + return Q::quantity-spec; +else + return q; +
    template<QuantitySpec QS, Unit U> + requires(!AssociatedUnit<U>) || UnitOf<U, QS{}> +consteval Reference auto make-reference(QS, U u); // exposition only +
    Effects: Equivalent to: +if constexpr (requires { requires get_quantity_spec(U{}) == QS{}; }) + return u; +else + return reference<QS, U>{}; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.static.html b/HEAD/api_reference/gen/qty.static.html new file mode 100644 index 00000000..2a48929f --- /dev/null +++ b/HEAD/api_reference/gen/qty.static.html @@ -0,0 +1,11 @@ +[qty.static]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.4 Static member functions [qty.static]

    static constexpr quantity zero() noexcept + requires see below; +static constexpr quantity one() noexcept + requires see below; +static constexpr quantity min() noexcept + requires see below; +static constexpr quantity max() noexcept + requires see below; +
    Let F be one of zero, one, min, and max.
    Returns: {representation_values<rep>​::​F(), R}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { representation_values<rep>::F(); } +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.sym.expr.algos.html b/HEAD/api_reference/gen/qty.sym.expr.algos.html new file mode 100644 index 00000000..b0bf65f6 --- /dev/null +++ b/HEAD/api_reference/gen/qty.sym.expr.algos.html @@ -0,0 +1,81 @@ +[qty.sym.expr.algos]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.4 Algorithms [qty.sym.expr.algos]

    template<typename T> +using expr-type = see below; // exposition only +
    expr-type<T> denotes +U if T is of the form power<U, Ints...>, and +T otherwise.
    template<typename T, typename U> +consteval bool type-less-impl(); // exposition only +
    Returns: true if T is less than U +in an implementation-defined total order for types, and +false otherwise.
    template<typename Lhs, typename Rhs> +struct type-less : // exposition only + std::bool_constant<is-specialization-of<Rhs, power>() || + type-less-impl<expr-type<Lhs>, expr-type<Rhs>>()> {}; +
    type-less meets the requirements of +the Pred parameter of the symbolic expression algorithms below.
    template<typename... Ts> +struct type-list {}; // exposition only + +template<typename OneType, typename... Ts> +struct expr-fractions { // exposition only + using num = see below; // exposition only + using den = see below; // exposition only +} +
    expr-fractions divides a symbolic expression to numerator and denominator parts.
    Let EF be a specialization of expr-fractions.
    • If EF is of the form expr-fractions<OneType, Ts..., per<Us...>>, +then +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<Us...>.
    • Otherwise, EF is of the form expr-fractions<OneType, Ts...>, and +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<>.
    The symbolic expression algorithms perform operations on symbolic constants.
    A symbolic constant is a type that is a model of SymbolicConstant.
    [Example 1: 
    The dimension dim_length, the quantity time, and the unit one are symbolic constants.
    — end example]
    +The algorithms also support +powers with a symbolic constant base and a rational exponent, +products thereof, and +fractions thereof.
    template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-multiply(Lhs, Rhs); // exposition only + +template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-divide(Lhs lhs, Rhs rhs); // exposition only + +template<template<typename...> typename To, typename OneType, typename T> +consteval auto expr-invert(T); // exposition only + +template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, + typename OneType, template<typename, typename> typename Pred = type-less, typename T> + requires(Den != 0) +consteval auto expr-pow(T); // exposition only +
    Mandates:
    • OneType is the neutral element (IEC 60050, 102-01-19) of the operation, and
    • Pred is a Cpp17BinaryTypeTrait (N4971, [meta.rqmts]) +with a base characteristic of std​::​bool_constant<B>.
      Pred<T, U> implements a total order for types; +B is true if T is ordered before U, and false otherwise.
    Effects:
    First, inputs to the operations are obtained from the types of the function parameters.
    If the type of a function parameter is: +
    • A specialization of To, +then its input is the product of its template arguments, and +the following also apply.
    • A specialization of per, +then its input is the product of the inverse of its template arguments, and +the following also apply.
    • A specialization of the form power<F, Num>, +then its input is , or +a specialization of the form power<F, Num, Den>, +then its input is , and +the following also applies.
    • Otherwise, the input is the symbolic constant itself.
    [Example 2: 
    Item by item, this algorithm step goes from the C++ parameter type +decltype(km / square(h)), +styled in diagnostics like +derived_unit<si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>, +
    • to decltype(km) ×per<power<decltype(h), 2> (product of To's arguments),
    • to (product of inverse of per's arguments),
    • to (powers as powers),
    • to where and (symbolic substitution) +in the mathematical domain.
    — end example]
    Then, the operation takes place: +
    • expr-multiply multiplies its inputs,
    • expr-divide divides the input of its first parameter by the input of its second parameter,
    • expr-invert divides 1 by its input, and
    • expr-pow raises its input to the .
    Finally, let r be the result of the operation simplified as follows: +
    • All terms are part of the same fraction (if any).
    • There is at most a single term with a given symbolic constant.
    • There are no negative exponents.
    • 1 is only present as r and as a numerator with a denominator not equal to 1.
    [Example 3: 
    Item by item:

    (single fraction)
    (unique symbolic constants)
    (positive exponents)
    (non-redundant 1s)
    — end example]
    Returns: r is mapped to the return type: +
    • If , returns OneType{}.
    • Otherwise, if r is a symbolic constant, returns r.
    • Otherwise, first applies the following mappings to the terms of r: +
      • is mapped to power<x, n, d>, and + is mapped to power<x, n>, and
      • 1 is mapped to OneType{}.
    • Then, a denominator x of r (if any) is mapped to per<x>.
    • Then, sorts r without per (if any) and +the template arguments of per (if any) +according to Pred.
    • Finally, returns To<r>{}, where per (if any) is the last argument.
    Remarks: A valid template argument list for To and per +is formed by interspersing commas between each mapped term.
    If a mapping to std​::​intmax_t is not representable, +the program is ill-formed.
    expr-map maps the contents of one symbolic expression to another resulting in a different type list.
    template<template<typename> typename Proj, template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename T> +consteval auto expr-map(T); // exposition only +
    Let +
    • expr-type-map<U> be +power<Proj<F>, Ints...> if U is of the form power<F, Ints...>, and +Proj<U> otherwise,
    • map-power(u) be +pow<Ints...>(F{}) if decltype(u) is of the form power<F, Ints...>, and +u otherwise, and
    • Nums and Dens +be packs denoting the template arguments of +T​::​nums and T​::​dens, respectively.
    Returns: (OneType{} * ... * map-power(expr-type-map<Nums>{})) / +(OneType{} * ... * map-power(expr-type-map<Dens>{})) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.sym.expr.concepts.html b/HEAD/api_reference/gen/qty.sym.expr.concepts.html new file mode 100644 index 00000000..0635b429 --- /dev/null +++ b/HEAD/api_reference/gen/qty.sym.expr.concepts.html @@ -0,0 +1,8 @@ +[qty.sym.expr.concepts]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.2 Concept SymbolicConstant [qty.sym.expr.concepts]

    template<typename T> +concept SymbolicConstant = // exposition only + std::is_empty_v<T> && std::is_final_v<T> && std::is_trivially_default_constructible_v<T> && + std::is_trivially_copy_constructible_v<T> && std::is_trivially_move_constructible_v<T> && + std::is_trivially_destructible_v<T>; +
    The concept SymbolicConstant +is used to constrain the types +that are used in symbolic expressions.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.sym.expr.general.html b/HEAD/api_reference/gen/qty.sym.expr.general.html new file mode 100644 index 00000000..21ea0b72 --- /dev/null +++ b/HEAD/api_reference/gen/qty.sym.expr.general.html @@ -0,0 +1,9 @@ +[qty.sym.expr.general]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.1 General [qty.sym.expr.general]

    Subclause [qty.sym.expr] specifies the components +used to maintain ordered, simplified, and readable +argument lists in the names of specializations.
    [Example 1: using namespace si::unit_symbols; +int x = kg * km / square(h); // error: cannot construct from + // derived_unit<si​::​kilo_<si​::​gram>, si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>> +
    +The library ensures decltype(kg * km / square(h)) is styled-like as commented in diagnostics, +provided that, in the implementation-defined total order of types, +decltype(kg) is less than decltype(km).
    — end example]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.sym.expr.html b/HEAD/api_reference/gen/qty.sym.expr.html new file mode 100644 index 00000000..18323579 --- /dev/null +++ b/HEAD/api_reference/gen/qty.sym.expr.html @@ -0,0 +1,123 @@ +[qty.sym.expr]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.1 General [qty.sym.expr.general]

    Subclause [qty.sym.expr] specifies the components +used to maintain ordered, simplified, and readable +argument lists in the names of specializations.
    [Example 1: using namespace si::unit_symbols; +int x = kg * km / square(h); // error: cannot construct from + // derived_unit<si​::​kilo_<si​::​gram>, si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>> +
    +The library ensures decltype(kg * km / square(h)) is styled-like as commented in diagnostics, +provided that, in the implementation-defined total order of types, +decltype(kg) is less than decltype(km).
    — end example]

    5.3.4.2 Concept SymbolicConstant [qty.sym.expr.concepts]

    template<typename T> +concept SymbolicConstant = // exposition only + std::is_empty_v<T> && std::is_final_v<T> && std::is_trivially_default_constructible_v<T> && + std::is_trivially_copy_constructible_v<T> && std::is_trivially_move_constructible_v<T> && + std::is_trivially_destructible_v<T>; +
    The concept SymbolicConstant +is used to constrain the types +that are used in symbolic expressions.

    5.3.4.3 Types [qty.sym.expr.types]

    namespace mp_units { + +template<typename T, typename... Ts> +struct per final {}; + +} +
    per is used to store arguments with negative exponents.
    A specialization of per +represents the product of the inverse of its template arguments.
    A program that instantiates a specialization of per +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +template<typename F, int Num, int... Den> + requires see below +struct power final { + using factor = F; // exposition only + static constexpr ratio exponent{Num, Den...}; // exposition only +}; + +} +
    power represents a power (IEC 60050, 102-02-08) +of the form .
    [Note 1: 
    Den is optional to shorten the type name when Den is 1.
    — end note]
    +A program that instantiates a specialization of power +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let r be ratio{Num, Den...}.
    Let is-valid-ratio be +true if r is a valid constant expression, and +false otherwise.
    The expression in the requires-clause is equivalent to: +is-valid-ratio && (r > ratio{0}) && (r != ratio{1}) +

    5.3.4.4 Algorithms [qty.sym.expr.algos]

    template<typename T> +using expr-type = see below; // exposition only +
    expr-type<T> denotes +U if T is of the form power<U, Ints...>, and +T otherwise.
    template<typename T, typename U> +consteval bool type-less-impl(); // exposition only +
    Returns: true if T is less than U +in an implementation-defined total order for types, and +false otherwise.
    template<typename Lhs, typename Rhs> +struct type-less : // exposition only + std::bool_constant<is-specialization-of<Rhs, power>() || + type-less-impl<expr-type<Lhs>, expr-type<Rhs>>()> {}; +
    type-less meets the requirements of +the Pred parameter of the symbolic expression algorithms below.
    template<typename... Ts> +struct type-list {}; // exposition only + +template<typename OneType, typename... Ts> +struct expr-fractions { // exposition only + using num = see below; // exposition only + using den = see below; // exposition only +} +
    expr-fractions divides a symbolic expression to numerator and denominator parts.
    Let EF be a specialization of expr-fractions.
    • If EF is of the form expr-fractions<OneType, Ts..., per<Us...>>, +then +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<Us...>.
    • Otherwise, EF is of the form expr-fractions<OneType, Ts...>, and +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<>.
    The symbolic expression algorithms perform operations on symbolic constants.
    A symbolic constant is a type that is a model of SymbolicConstant.
    [Example 1: 
    The dimension dim_length, the quantity time, and the unit one are symbolic constants.
    — end example]
    +The algorithms also support +powers with a symbolic constant base and a rational exponent, +products thereof, and +fractions thereof.
    template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-multiply(Lhs, Rhs); // exposition only + +template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-divide(Lhs lhs, Rhs rhs); // exposition only + +template<template<typename...> typename To, typename OneType, typename T> +consteval auto expr-invert(T); // exposition only + +template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, + typename OneType, template<typename, typename> typename Pred = type-less, typename T> + requires(Den != 0) +consteval auto expr-pow(T); // exposition only +
    Mandates:
    • OneType is the neutral element (IEC 60050, 102-01-19) of the operation, and
    • Pred is a Cpp17BinaryTypeTrait (N4971, [meta.rqmts]) +with a base characteristic of std​::​bool_constant<B>.
      Pred<T, U> implements a total order for types; +B is true if T is ordered before U, and false otherwise.
    Effects:
    First, inputs to the operations are obtained from the types of the function parameters.
    If the type of a function parameter is: +
    • A specialization of To, +then its input is the product of its template arguments, and +the following also apply.
    • A specialization of per, +then its input is the product of the inverse of its template arguments, and +the following also apply.
    • A specialization of the form power<F, Num>, +then its input is , or +a specialization of the form power<F, Num, Den>, +then its input is , and +the following also applies.
    • Otherwise, the input is the symbolic constant itself.
    [Example 2: 
    Item by item, this algorithm step goes from the C++ parameter type +decltype(km / square(h)), +styled in diagnostics like +derived_unit<si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>, +
    • to decltype(km) ×per<power<decltype(h), 2> (product of To's arguments),
    • to (product of inverse of per's arguments),
    • to (powers as powers),
    • to where and (symbolic substitution) +in the mathematical domain.
    — end example]
    Then, the operation takes place: +
    • expr-multiply multiplies its inputs,
    • expr-divide divides the input of its first parameter by the input of its second parameter,
    • expr-invert divides 1 by its input, and
    • expr-pow raises its input to the .
    Finally, let r be the result of the operation simplified as follows: +
    • All terms are part of the same fraction (if any).
    • There is at most a single term with a given symbolic constant.
    • There are no negative exponents.
    • 1 is only present as r and as a numerator with a denominator not equal to 1.
    [Example 3: 
    Item by item:

    (single fraction)
    (unique symbolic constants)
    (positive exponents)
    (non-redundant 1s)
    — end example]
    Returns: r is mapped to the return type: +
    • If , returns OneType{}.
    • Otherwise, if r is a symbolic constant, returns r.
    • Otherwise, first applies the following mappings to the terms of r: +
      • is mapped to power<x, n, d>, and + is mapped to power<x, n>, and
      • 1 is mapped to OneType{}.
    • Then, a denominator x of r (if any) is mapped to per<x>.
    • Then, sorts r without per (if any) and +the template arguments of per (if any) +according to Pred.
    • Finally, returns To<r>{}, where per (if any) is the last argument.
    Remarks: A valid template argument list for To and per +is formed by interspersing commas between each mapped term.
    If a mapping to std​::​intmax_t is not representable, +the program is ill-formed.
    expr-map maps the contents of one symbolic expression to another resulting in a different type list.
    template<template<typename> typename Proj, template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename T> +consteval auto expr-map(T); // exposition only +
    Let +
    • expr-type-map<U> be +power<Proj<F>, Ints...> if U is of the form power<F, Ints...>, and +Proj<U> otherwise,
    • map-power(u) be +pow<Ints...>(F{}) if decltype(u) is of the form power<F, Ints...>, and +u otherwise, and
    • Nums and Dens +be packs denoting the template arguments of +T​::​nums and T​::​dens, respectively.
    Returns: (OneType{} * ... * map-power(expr-type-map<Nums>{})) / +(OneType{} * ... * map-power(expr-type-map<Dens>{})) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.sym.expr.types.html b/HEAD/api_reference/gen/qty.sym.expr.types.html new file mode 100644 index 00000000..88134da4 --- /dev/null +++ b/HEAD/api_reference/gen/qty.sym.expr.types.html @@ -0,0 +1,28 @@ +[qty.sym.expr.types]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.3 Types [qty.sym.expr.types]

    namespace mp_units { + +template<typename T, typename... Ts> +struct per final {}; + +} +
    per is used to store arguments with negative exponents.
    A specialization of per +represents the product of the inverse of its template arguments.
    A program that instantiates a specialization of per +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +template<typename F, int Num, int... Den> + requires see below +struct power final { + using factor = F; // exposition only + static constexpr ratio exponent{Num, Den...}; // exposition only +}; + +} +
    power represents a power (IEC 60050, 102-02-08) +of the form .
    [Note 1: 
    Den is optional to shorten the type name when Den is 1.
    — end note]
    +A program that instantiates a specialization of power +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let r be ratio{Num, Den...}.
    Let is-valid-ratio be +true if r is a valid constant expression, and +false otherwise.
    The expression in the requires-clause is equivalent to: +is-valid-ratio && (r > ratio{0}) && (r != ratio{1}) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.sym.txt.html b/HEAD/api_reference/gen/qty.sym.txt.html new file mode 100644 index 00000000..ab898951 --- /dev/null +++ b/HEAD/api_reference/gen/qty.sym.txt.html @@ -0,0 +1,80 @@ +[qty.sym.txt]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.3 Symbol text [qty.sym.txt]

    namespace mp_units { + +template<std::size_t N, std::size_t M> +class symbol_text { +public: + std::fixed_u8string<N> utf8; // exposition only + std::fixed_string<M> portable; // exposition only + + // constructors + constexpr symbol_text(char portable); + consteval symbol_text(const char (&portable)[N + 1]); + constexpr symbol_text(const std::fixed_string<N>& portable); + consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); + constexpr symbol_text(const std::fixed_u8string<N>& utf8, + const std::fixed_string<M>& portable); + + // observers + constexpr const auto& utf8() const { return utf8; } + constexpr const auto& portable() const { return portable; } + constexpr bool empty() const { return utf8().empty(); } + + // string operations + template<std::size_t N2, std::size_t M2> + friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); + + // comparison + template<std::size_t N2, std::size_t M2> + friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; + template<std::size_t N2, std::size_t M2> + friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +}; + +symbol_text(char) -> symbol_text<1, 1>; + +template<std::size_t N> +symbol_text(const char (&)[N]) -> symbol_text<N - 1, N - 1>; + +template<std::size_t N> +symbol_text(const std::fixed_string<N>&) -> symbol_text<N, N>; + +template<std::size_t N, std::size_t M> +symbol_text(const char8_t (&)[N], const char (&)[M]) -> symbol_text<N - 1, M - 1>; + +template<std::size_t N, std::size_t M> +symbol_text(const std::fixed_u8string<N>&, const std::fixed_string<M>&) -> symbol_text<N, M>; + +} +
    symbol_text represents a symbol text.
    utf8 stores its UTF-8 representation, and +portable stores its portable representation.
    symbol_text<N, M> is a structural type (N4971, [temp.param]).
    In the descriptions that follow, +it is a Precondition that +
    • values of char are in the basic literal character set (N4971, [lex.charset]), and
    • for a parameter of the form const CharT (&txt)[M], +(txt[M - 1] == CharT()) is true.
    constexpr symbol_text(char portable); +consteval symbol_text(const char (&portable)[N + 1]); +constexpr symbol_text(const std::fixed_string<N>& portable); +consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); +constexpr symbol_text(const std::fixed_u8string<N>& utf8, const std::fixed_string<M>& portable); +
    For the constructors without a parameter named utf8, +let utf8 be: +std::bit_cast<std::fixed_u8string<N>>(std::basic_fixed_string(portable)) +
    Effects: Equivalent to the mem-initializer-list: +utf8{utf8}, portable{portable} +
    template<std::size_t N2, std::size_t M2> +friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); +
    Effects: Equivalent to: +return symbol_text<N + N2, M + M2>(lhs.utf8() + rhs.utf8(), + lhs.portable() + rhs.portable()); +
    template<std::size_t N2, std::size_t M2> +friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +template<std::size_t N2, std::size_t M2> +friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +
    Let @ be the operator.
    Effects: Equivalent to: +return std::make_tuple(std::cref(lhs.utf8()), std::cref(lhs.portable())) @ + std::make_tuple(std::cref(rhs.utf8()), std::cref(rhs.portable())); +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.syn.html b/HEAD/api_reference/gen/qty.syn.html new file mode 100644 index 00000000..bf079dc3 --- /dev/null +++ b/HEAD/api_reference/gen/qty.syn.html @@ -0,0 +1,334 @@ +[qty.syn]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.3 Class template quantity [qty.syn]

    namespace mp_units { + +template<typename T> +concept Quantity = (is-derived-from-specialization-of<T, quantity>()); // exposition only + +template<typename Q, auto QS> +concept QuantityOf = // exposition only + Quantity<Q> && QuantitySpecOf<decltype(auto(Q::quantity_spec)), QS>; + +template<Unit UFrom, Unit UTo> +consteval bool integral-conversion-factor(UFrom from, UTo to) // exposition only +{ + return is-integral(get-canonical-unit(from).mag / get-canonical-unit(to).mag); +} + +template<typename T> +concept IsFloatingPoint = treat_as_floating_point<T>; // exposition only + +template<typename FromRep, typename ToRep, auto FromUnit = one, auto ToUnit = one> +concept ValuePreservingTo = // exposition only + Representation<std::remove_cvref_t<FromRep>> && Representation<ToRep> && + Unit<decltype(FromUnit)> && Unit<decltype(ToUnit)> && std::assignable_from<ToRep&, FromRep> && + (IsFloatingPoint<ToRep> || (!IsFloatingPoint<std::remove_cvref_t<FromRep>> && + (integral-conversion-factor(FromUnit, ToUnit)))); + +template<typename QFrom, typename QTo> +concept QuantityConvertibleTo = // exposition only + Quantity<QFrom> && Quantity<QTo> && + QuantitySpecConvertibleTo<QFrom::quantity_spec, QTo::quantity_spec> && + UnitConvertibleTo<QFrom::unit, QTo::unit> && + ValuePreservingTo<typename QFrom::rep, typename QTo::rep, QFrom::unit, QTo::unit> && + requires(QFrom q) { sudo-cast<QTo>(q); }; // see [qty.non.mem.conv] + +template<auto QS, typename Func, typename T, typename U> +concept InvokeResultOf = // exposition only + QuantitySpec<decltype(QS)> && std::regular_invocable<Func, T, U> && + RepresentationOf<std::invoke_result_t<Func, T, U>, QS>; + +template<typename Func, typename Q1, typename Q2, + auto QS = std::invoke_result_t<Func, decltype(auto(Q1::quantity_spec)), + decltype(auto(Q2::quantity_spec))>{}> +concept InvocableQuantities = // exposition only + QuantitySpec<decltype(QS)> && Quantity<Q1> && Quantity<Q2> && + InvokeResultOf<QS, Func, typename Q1::rep, typename Q2::rep>; + +template<auto R1, auto R2> +concept HaveCommonReference = requires { get_common_reference(R1, R2); }; // exposition only + +template<typename Func, Quantity Q1, Quantity Q2> +using common-quantity-for = // exposition only + quantity<get_common_reference(Q1::reference, Q2::reference), + std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>; + +template<typename Func, typename Q1, typename Q2> +concept CommonlyInvocableQuantities = // exposition only + Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> && + std::convertible_to<Q1, common-quantity-for<Func, Q1, Q2>> && + std::convertible_to<Q2, common-quantity-for<Func, Q1, Q2>> && + InvocableQuantities<Func, Q1, Q2, + get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>; + +template<auto R1, auto R2, typename Rep1, typename Rep2> +concept SameValueAs = // exposition only + (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>; + +template<typename T> +using quantity-like-type = // exposition only + quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; + +template<typename T, typename U, typename TT = std::remove_reference_t<T>> +concept Mutable = (!std::is_const_v<TT>) && std::derived_from<TT, U>; // exposition only + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity { +public: + Rep numerical-value; // exposition only + + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + using rep = Rep; + + // [qty.static], static member functions + static constexpr quantity zero() noexcept + requires see below; + static constexpr quantity one() noexcept + requires see below; + static constexpr quantity min() noexcept + requires see below; + static constexpr quantity max() noexcept + requires see below; + + // [qty.cons], constructors and assignment + + quantity() = default; + quantity(const quantity&) = default; + quantity(quantity&&) = default; + ~quantity() = default; + + template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> + constexpr quantity(FwdValue&& v, R2); + + template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> + constexpr quantity(FwdValue&& v, R2); + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity(FwdValue&& v); + + template<QuantityConvertibleTo<quantity> Q> + constexpr explicit(see below) quantity(const Q& q); + + template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> + constexpr explicit(see below) quantity(const Q& q); + + quantity& operator=(const quantity&) = default; + quantity& operator=(quantity&&) = default; + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity& operator=(FwdValue&& v); + + // [qty.conv], conversions + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> + constexpr QuantityOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + // [qty.obs], numerical value observers + + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr rep& numerical_value_ref_in(U) & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr const rep& numerical_value_ref_in(U) const & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + void numerical_value_ref_in(U) const && = delete; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> + constexpr rep numerical_value_in(U) const noexcept; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } + constexpr rep force_numerical_value_in(U) const noexcept; + + // [qty.conv.ops], conversion operations + + template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) + explicit operator V_() const & noexcept; + + template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> + constexpr explicit(see below) operator Q_() const noexcept(see below); + + // [qty.unary.ops], unary operations + + constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; + constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; + + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator++(Q&& q) + requires see below; + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator--(Q&& q) + requires see below; + + constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; + constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; + + // [qty.assign.ops], compound assignment operations + + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); + + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); + + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); + + // [qty.arith.ops], arithmetic operations + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); + + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> + friend constexpr Quantity auto operator/(const Value&, const Q&); + + // [qty.cmp], comparison + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr bool operator==(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); + + // [qty.val.cmp], value comparison + friend constexpr bool is_eq_zero(const quantity& q) requires see below; + friend constexpr bool is_neq_zero(const quantity& q) requires see below; + friend constexpr bool is_lt_zero(const quantity& q) requires see below; + friend constexpr bool is_gt_zero(const quantity& q) requires see below; + friend constexpr bool is_lteq_zero(const quantity& q) requires see below; + friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +}; + +template<Representation Value, Reference R> +quantity(Value, R) -> quantity<R{}, Value>; + +template<Representation Value> +quantity(Value) -> quantity<one, Value>; + +template<QuantityLike Q> +explicit(quantity_like_traits<Q>::explicit_import) quantity(Q) + -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>; + +} +
    quantity<R, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.systems.html b/HEAD/api_reference/gen/qty.systems.html index 3429c9d7..00ec3463 100644 --- a/HEAD/api_reference/gen/qty.systems.html +++ b/HEAD/api_reference/gen/qty.systems.html @@ -1 +1 @@ -[qty.systems]

    5 Quantities library [qties]

    5.11 Systems [qty.systems]

    \ No newline at end of file +[qty.systems]

    5 Quantities and units library [quantities]

    5.8 Systems [qty.systems]

    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.traits.html b/HEAD/api_reference/gen/qty.traits.html deleted file mode 100644 index dbb5bf72..00000000 --- a/HEAD/api_reference/gen/qty.traits.html +++ /dev/null @@ -1,17 +0,0 @@ -[qty.traits]

    5 Quantities library [qties]

    5.6 Traits [qty.traits]

    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; -
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), -users may specialize is_scalar, is_vector, and is_tensor to true -for cv-unqualified program-defined types -which respectively represent -a scalar (IEC 60050, 102-02-18), -a vector (IEC 60050, 102-03-04), and -a tensor, -and false for types which respectively do not.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.type.html b/HEAD/api_reference/gen/qty.type.html deleted file mode 100644 index 454c9b7d..00000000 --- a/HEAD/api_reference/gen/qty.type.html +++ /dev/null @@ -1,10 +0,0 @@ -[qty.type]

    5 Quantities library [qties]

    5.8 Types [qty.types]

    5.8.2 Class template quantity [qty.type]

    namespace mp_units { - -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> -class quantity { unspecified }; - -} -
    Let Q be a specialization of quantity.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.types.general.html b/HEAD/api_reference/gen/qty.types.general.html deleted file mode 100644 index 49e06948..00000000 --- a/HEAD/api_reference/gen/qty.types.general.html +++ /dev/null @@ -1,8 +0,0 @@ -[qty.types.general]

    5 Quantities library [qties]

    5.8 Types [qty.types]

    5.8.1 General [qty.types.general]

    A quantity type -is a type Q -that is a specialization of quantity or quantity_point.
    Q represents a quantity (IEC 60050, 112-01-01) -with Q​::​rep as its number -and Q​::​reference as its reference.
    Q is a structural type (N4971, [temp.param]) -if Q​::​rep is a structural type.
    Each class template defined in subclause [qty.types] -has data members and special members specified below, and -has no base classes or members other than those specified.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.types.html b/HEAD/api_reference/gen/qty.types.html deleted file mode 100644 index 3e07c8ff..00000000 --- a/HEAD/api_reference/gen/qty.types.html +++ /dev/null @@ -1,27 +0,0 @@ -[qty.types]

    5 Quantities library [qties]

    5.8 Types [qty.types]

    5.8.1 General [qty.types.general]

    A quantity type -is a type Q -that is a specialization of quantity or quantity_point.
    Q represents a quantity (IEC 60050, 112-01-01) -with Q​::​rep as its number -and Q​::​reference as its reference.
    Q is a structural type (N4971, [temp.param]) -if Q​::​rep is a structural type.
    Each class template defined in subclause [qty.types] -has data members and special members specified below, and -has no base classes or members other than those specified.

    5.8.2 Class template quantity [qty.type]

    namespace mp_units { - -export template<some_reference auto R, - representation_of<get_quantity_spec(R).character> Rep = double> -class quantity { unspecified }; - -} -
    Let Q be a specialization of quantity.

    5.8.3 Class template quantity_point [qty.point.type]

    namespace mp_units { - -export template<unspecified> -class quantity_point { unspecified }; - -} -
    A quantity point type is a specialization of quantity_point.
    Let Q be a quantity point type.
    Q​::​point_origin represents -the origin point of a position vector (IEC 60050, 102-03-15).
    • If Rep is a scalar, -Q represents the scalar quantity (IEC 60050, 102-02-19) -of a position vector.
    • If Rep is a vector, -Q represents a position vector.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unary.ops.html b/HEAD/api_reference/gen/qty.unary.ops.html new file mode 100644 index 00000000..09a914c6 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unary.ops.html @@ -0,0 +1,31 @@ +[qty.unary.ops]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.9 Unary operations [qty.unary.ops]

    In the following descriptions, +let @ be the operator.
    constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; +constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{@numerical-value, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(const rep v) { + { @v } -> std::common_with<rep>; +} +
    template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator++(Q&& q) + requires see below; +template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator--(Q&& q) + requires see below; +
    Effects: Equivalent to +@q.numerical-value.
    Returns: std​::​forward<Q>(q).
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { @v } -> std::same_as<rep&>; +} +
    constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; +constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{numerical-value@, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { v@ } -> std::common_with<rep>; +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.cmp.html b/HEAD/api_reference/gen/qty.unit.cmp.html new file mode 100644 index 00000000..e5942976 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.cmp.html @@ -0,0 +1,20 @@ +[qty.unit.cmp]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.7 Comparison [qty.unit.cmp]

    template<Unit Lhs, Unit Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    template<Unit Lhs, Unit Rhs> +friend consteval bool equivalent(Lhs lhs, Rhs rhs); +
    Effects: Equivalent to: +const auto lhs_canonical = get-canonical-unit(lhs); +const auto rhs_canonical = get-canonical-unit(rhs); +return lhs_canonical.mag == rhs_canonical.mag && + lhs_canonical.reference_unit == rhs_canonical.reference_unit; +
    template<Unit From, Unit To> +consteval bool convertible(From from, To to); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<From, To>) + return true; +else if constexpr (PotentiallyConvertibleTo<From, To>) + return std::is_same_v<decltype(get-canonical-unit(from).reference_unit), + decltype(get-canonical-unit(to).reference_unit)>; +else + return false; +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.concepts.html b/HEAD/api_reference/gen/qty.unit.concepts.html new file mode 100644 index 00000000..f414e9ca --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.concepts.html @@ -0,0 +1,34 @@ +[qty.unit.concepts]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.4 Concepts [qty.unit.concepts]

    template<typename T> +concept Unit = SymbolicConstant<T> && std::derived_from<T, unit-interface>; + +template<typename T> +concept PrefixableUnit = Unit<T> && is-derived-from-specialization-of<T, named_unit>(); + +template<typename T> +concept AssociatedUnit = Unit<U> && has-associated-quantity(U{}); + +template<typename U, auto QS> +concept UnitOf = AssociatedUnit<U> && QuantitySpec<decltype(QS)> && + QuantitySpecConvertibleTo<get_quantity_spec(U{}), QS> && + (get_kind(QS) == get_kind(get_quantity_spec(U{})) || + !NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>); + +template<auto From, auto To> +concept UnitConvertibleTo = // exposition only + Unit<decltype(From)> && Unit<decltype(To)> && (convertible(From, To)); + +template<typename U, auto FromU, auto QS> +concept UnitCompatibleWith = // exposition only + Unit<U> && Unit<decltype(FromU)> && QuantitySpec<decltype(QS)> && + (!AssociatedUnit<U> || UnitOf<U, QS>) && UnitConvertibleTo<FromU, U{}>; + +template<typename T> +concept OffsetUnit = Unit<T> && requires { T::point-origin; }; // exposition only + +template<typename From, typename To> +concept PotentiallyConvertibleTo = // exposition only + Unit<From> && Unit<To> && + ((AssociatedUnit<From> && AssociatedUnit<To> && + implicitly_convertible(get_quantity_spec(From{}), get_quantity_spec(To{}))) || + (!AssociatedUnit<From> && !AssociatedUnit<To>)); +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.general.html b/HEAD/api_reference/gen/qty.unit.general.html new file mode 100644 index 00000000..0d1bd30c --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.general.html @@ -0,0 +1,2 @@ +[qty.unit.general]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.1 General [qty.unit.general]

    Subclause [qty.unit] specifies the components +for defining a unit of measurement (IEC 60050, 112-01-14).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.html b/HEAD/api_reference/gen/qty.unit.html new file mode 100644 index 00000000..f4f3ab1a --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.html @@ -0,0 +1,466 @@ +[qty.unit]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.1 General [qty.unit.general]

    Subclause [qty.unit] specifies the components +for defining a unit of measurement (IEC 60050, 112-01-14).

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.1 General [qty.unit.mag.general]

    Subclause [qty.unit.mag] specifies the components +used to represent the numerical value (IEC 60050, 112-01-29) of a unit +with support for powers (IEC 60050, 102-02-08) of real numbers (IEC 60050, 102-02-05).

    5.4.4.2.2 Concepts [qty.unit.mag.concepts]

    template<typename T> +concept MagConstant = SymbolicConstant<T> && is-derived-from-specialization-of<T, mag_constant>(); + +template<typename T> +concept UnitMagnitude = (is-specialization-of<T, unit-magnitude>()); + +template<typename T> +concept MagArg = std::integral<T> || MagConstant<T>; // exposition only +

    5.4.4.2.3 Types [qty.unit.mag.types]

    namespace mp_units { + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant { + static constexpr auto symbol = Symbol; // exposition only + static constexpr long double value = Value; // exposition only +}; + +} +
    A specialization of mag_constant represents a real number (IEC 60050, 102-02-05).
    Symbol is its symbol, and +Value is (an approximation of) its value.
    namespace mp_units { + +template<auto... Ms> +struct unit-magnitude { // exposition only + // [qty.unit.mag.ops], operations + + template<UnitMagnitude M> + friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); + + friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); + + template<UnitMagnitude Rhs> + friend consteval bool operator==(unit-magnitude, Rhs); + + template<int Num, int Den = 1> + friend consteval auto pow(unit-magnitude); // exposition only + + // [qty.unit.mag.utils], utilities + + friend consteval bool is-positive-integral-power(unit-magnitude); // exposition only + + template<auto... Ms2> + friend consteval auto common-magnitude(unit-magnitude, // exposition only + unit-magnitude<Ms2...>); +}; + +} +
    A specialization of unit-magnitude +represents the product of its template arguments.
    For the purposes of specifying the implementation-defined limits, +let the representation of the terms of unit-magnitude be the structure +struct { + ratio exp; + base-type base; +}; + +representing the number , +where base-type is a model of MagArg.
    • There is a single term for each base-type.
    • exp.num is not expanded into base.
      [Note 1: 
      is not permitted.
      — end note]
    • exp.den can reduce the base.
      [Note 2: 
      is permitted.
      — end note]
    • If the result of an operation on std​::​intmax_t values is undefined, +the behavior is +implementation-defined.

    5.4.4.2.4 Operations [qty.unit.mag.ops]

    template<UnitMagnitude M> +friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); +
    Returns:
    • If sizeof...(Ms) == 0 is true, returns rhs.
    • Otherwise, if std​::​is_same_v<M, unit-magnitude<>>, returns lhs.
    • Otherwise, returns an unspecified value equal to lhs ×rhs.
    friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); +
    Returns: lhs * pow<-1>(rhs).
    template<UnitMagnitude Rhs> +friend consteval bool operator==(unit-magnitude, Rhs); +
    Returns: std​::​is_same_v<unit-magnitude, Rhs>.
    template<int Num, int Den = 1> +friend consteval auto pow(unit-magnitude base); // exposition only +
    Returns:
    • If Num == 0 is true, returns unit-magnitude<>{}.
    • Otherwise, returns an unspecified value equal to .
    template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; +
    Constraints: V is greater than 0.
    Effects: If MagConstant<decltype(V)> is satisfied, +initializes mag with unit-magnitude<V>{}.
    Otherwise, initializes mag with +an unspecified value equal to V.
    template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; +
    Effects: Initializes mag_ratio with +an unspecified value equal to .
    template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = pow<Num, Den>(mag<Base>); +
    Constraints: Base is greater than 0.

    5.4.4.2.5 Utilities [qty.unit.mag.utils]

    friend consteval bool is-positive-integral-power(unit-magnitude x); // exposition only +
    Returns: false if x has a negative or rational exponent, and +true otherwise.
    template<auto... Ms2> +friend consteval auto common-magnitude(unit-magnitude, unit-magnitude<Ms2...>); // exposition only +
    Returns: The largest magnitude C +such that each input magnitude is expressible +by only positive powers relative to C.

    5.4.4.3 Traits [qty.unit.traits]

    template<Unit auto U> +constexpr bool space_before_unit_symbol = true; +
    The formatting functions ([qty.unit.sym.fmt]) use space_before_unit_symbol +to determine whether there is a space +between the numerical value and the unit symbol.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize space_before_unit_symbol +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.4.4.4 Concepts [qty.unit.concepts]

    template<typename T> +concept Unit = SymbolicConstant<T> && std::derived_from<T, unit-interface>; + +template<typename T> +concept PrefixableUnit = Unit<T> && is-derived-from-specialization-of<T, named_unit>(); + +template<typename T> +concept AssociatedUnit = Unit<U> && has-associated-quantity(U{}); + +template<typename U, auto QS> +concept UnitOf = AssociatedUnit<U> && QuantitySpec<decltype(QS)> && + QuantitySpecConvertibleTo<get_quantity_spec(U{}), QS> && + (get_kind(QS) == get_kind(get_quantity_spec(U{})) || + !NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>); + +template<auto From, auto To> +concept UnitConvertibleTo = // exposition only + Unit<decltype(From)> && Unit<decltype(To)> && (convertible(From, To)); + +template<typename U, auto FromU, auto QS> +concept UnitCompatibleWith = // exposition only + Unit<U> && Unit<decltype(FromU)> && QuantitySpec<decltype(QS)> && + (!AssociatedUnit<U> || UnitOf<U, QS>) && UnitConvertibleTo<FromU, U{}>; + +template<typename T> +concept OffsetUnit = Unit<T> && requires { T::point-origin; }; // exposition only + +template<typename From, typename To> +concept PotentiallyConvertibleTo = // exposition only + Unit<From> && Unit<To> && + ((AssociatedUnit<From> && AssociatedUnit<To> && + implicitly_convertible(get_quantity_spec(From{}), get_quantity_spec(To{}))) || + (!AssociatedUnit<From> && !AssociatedUnit<To>)); +

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.1 Canonical [qty.canon.unit]

    namespace mp_units { + +template<UnitMagnitude M, Unit U> +struct canonical-unit { // exposition only + M mag; + U reference_unit; +}; + +} +
    canonical-unit represents a unit expressed in terms of base units (IEC 60050, 112-01-18).
    [Note 1: 
    Other types representing units are equal only if they have the same type.
    canonical-unit is used to implement binary relations other than equality.
    — end note]
    reference_unit is simplified ([qty.sym.expr.algos]).
    consteval auto get-canonical-unit(Unit auto u); // exposition only +
    Returns: The instantiation of canonical-unit for u.

    5.4.4.5.2 Scaled [qty.scaled.unit]

    namespace mp_units { + +template<UnitMagnitude auto M, Unit U> + requires(M != unit-magnitude<>{} && M != mag<1>) +struct scaled_unit final : unit-interface { + using base-type = scaled_unit; // exposition only + static constexpr UnitMagnitude auto mag = M; // exposition only + static constexpr U reference-unit{}; // exposition only + static constexpr auto point-origin = U::point_origin; // exposition only, present only + // if the qualified-id U​::​point_origin is valid and denotes an object +}; + +} +
    scaled_unit<M, U> is used by the library +to represent the unit M ×U.

    5.4.4.5.3 Named [qty.named.unit]

    namespace mp_units { + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS, PO> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol> + requires(!Symbol.empty()) +struct named_unit<Symbol> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U> + requires(!Symbol.empty()) +struct named_unit<Symbol, U> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires(!Symbol.empty()) +struct named_unit<Symbol, U, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +} +
    A named unit is a type that models PrefixableUnit.
    A specialization of named_unit is used as a base type when defining a named unit.
    In the following descriptions, let U be a named unit defined with an alluded signature.
    The identifier of U represents +its unit name (IEC 60050, 112-01-15) +or special unit name (IEC 60050, 112-01-16).
    Symbol is its unit symbol (IEC 60050, 112-01-17).
    The possible arguments to named_unit are +
    • ,
    • ,
    • , and
    • .
    The first signature defines the unit of a base quantity +without a unit prefix (IEC 60050, 112-01-26).
    The second signature defines a unit +that can be reused by several base quantities.
    The third and fourth signatures with a unit expression argument E +define U as implicitly convertible from E.
    The first and fourth signatures with a kind of quantity (IEC 60050, 112-01-04) Q +also restrict U to Q.
    A point origin argument specifies the default point origin of U ([qty.pt.syn]).
    [Example 1: // 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; // . + +// The fourth signature also further restricts the kind of quantity. +inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { +} hertz; // Hz can't measure becquerel, activity, + // or any other quantity with dimension + // that isn't a kind of frequency. + — end example]

    5.4.4.5.4 Prefixed [qty.prefixed.unit]

    namespace mp_units { + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires(!Symbol.empty()) +struct prefixed_unit : decltype(M * U)::base-type { + using base-type = prefixed_unit; // exposition only + static constexpr auto symbol = Symbol + U.symbol; // exposition only +}; + +} +
    prefixed_unit<Symbol, M, U> represents the unit U with a unit prefix (IEC 60050, 112-01-26).
    Symbol is the symbol of the unit prefix.
    M is the factor of the unit prefix.
    A specialization of prefixed_unit is used as a base type when defining a unit prefix.
    [Example 1: template<PrefixableUnit auto U> +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + +template<PrefixableUnit auto U> +constexpr kilo_<U> kilo; + +inline constexpr auto kilogram = kilo<si::gram>; + — end example]

    5.4.4.5.5 Common [qty.common.unit]

    namespace mp_units { + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit final : decltype(get-common-scaled-unit(U1{}, U2{}, Rest{}...))::base-type +{ + using base-type = common_unit; // exposition only + static constexpr auto common-unit = // exposition only + get-common-scaled-unit(U1{}, U2{}, Rest{}...); +}; + +} +
    common_unit is used by the library +to encapsulate a conversion factor between units (IEC 60050, 112-01-33) +common to the operands of quantity addition.
    [Example 1: 
    The result of 1 * km + 1 * mi +has a common unit +encapsulated by common_unit<mi, km>.
    — end example]
    +A program that instantiates a specialization of common_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    template<Unit U1, Unit U2, Unit... Rest> +consteval Unit auto get-common-scaled-unit(U1, U2, Rest... rest) // exposition only + requires see below; +
    Effects: Equivalent to: +constexpr auto res = [] { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + constexpr auto common_mag = common-magnitude(canonical_lhs.mag, canonical_rhs.mag); + if constexpr (common_mag == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit<common_mag, decltype(auto(canonical_lhs.reference_unit))>{}; +}(); +if constexpr (sizeof...(rest) == 0) + return res; +else + return get-common-scaled-unit(res, rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(U1{}, U2{}) && (sizeof...(Rest) == 0 || requires { + get-common-scaled-unit(get-common-scaled-unit(u1, u2), rest...); + })) +

    5.4.4.5.6 Derived [qty.derived.unit]

    namespace mp_units { + +template<typename... Expr> +struct derived-unit-impl : // exposition only + unit-interface, + expr-fractions<struct one, Expr...> { + using base-type = derived-unit-impl; // exposition only +}; + +template<SymbolicConstant... Expr> +struct derived_unit final : derived-unit-impl<Expr...> {}; + +} +
    derived_unit is used by the library +to represent a derived unit (IEC 60050, 112-01-19).
    [Example 1: using namespace si::unit_symbols; +int x = m * m; // error: cannot construct from derived_unit<power<si​::​metre, 2>> +int y = m * s; // error: cannot construct from derived_unit<si​::​metre, si​::​second> +int z = m / s; // error: cannot construct from derived_unit<si​::​metre, per<si​::​second>> + — end example]
    +A program that instantiates a specialization of derived_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.

    5.4.4.5.7 One [qty.unit.one]

    namespace mp_units { + +struct one final : derived-unit-impl<> {}; + +} +
    one represents the base unit (IEC 60050, 112-01-18) of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.4.6 Operations [qty.unit.ops]

    namespace mp_units { + +struct unit-interface { // exposition only + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator*(M, U u); + + friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; + + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator/(M mag, U u); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); + + // [qty.unit.cmp], comparison + + template<Unit Lhs, Unit Rhs> + friend consteval bool operator==(Lhs, Rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval bool equivalent(Lhs lhs, Rhs rhs); +}; + +} +
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator*(M, U u); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<M, decltype(auto(mag<1>))>) + return u; +else if constexpr (is-specialization-of<U, scaled_unit>()) { + if constexpr (M{} * U::mag == mag<1>) + return U::reference-unit; + else + return scaled_unit<M{} * U::mag, decltype(auto(U::reference-unit))>{}; +} else + return scaled_unit<M{}, U>{}; +
    friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; +
    Recommended practice: Suggest swapping the operands.
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator/(M mag, U u); +
    Returns: mag * inverse(u).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); +
    Returns: expr-multiply<derived_unit, struct one>(lhs, rhs).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); +
    Returns: expr-divide<derived_unit, struct one>(lhs, rhs).
    consteval Unit auto inverse(Unit auto u); +
    Returns: one / u.
    template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires(Den != 0) +consteval Unit auto pow(U u); +
    Returns: expr-pow<Num, Den, derived_unit, struct one>(u).
    consteval Unit auto sqrt(Unit auto u); +
    Returns: pow<1, 2>(u).
    consteval Unit auto cbrt(Unit auto u); +
    Returns: pow<1, 3>(u).
    consteval Unit auto square(Unit auto u); +
    Returns: pow<2>(u).
    consteval Unit auto cubic(Unit auto u); +
    Returns: pow<3>(u).

    5.4.4.7 Comparison [qty.unit.cmp]

    template<Unit Lhs, Unit Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    template<Unit Lhs, Unit Rhs> +friend consteval bool equivalent(Lhs lhs, Rhs rhs); +
    Effects: Equivalent to: +const auto lhs_canonical = get-canonical-unit(lhs); +const auto rhs_canonical = get-canonical-unit(rhs); +return lhs_canonical.mag == rhs_canonical.mag && + lhs_canonical.reference_unit == rhs_canonical.reference_unit; +
    template<Unit From, Unit To> +consteval bool convertible(From from, To to); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<From, To>) + return true; +else if constexpr (PotentiallyConvertibleTo<From, To>) + return std::is_same_v<decltype(get-canonical-unit(from).reference_unit), + decltype(get-canonical-unit(to).reference_unit)>; +else + return false; +

    5.4.4.8 Observers [qty.unit.obs]

    consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +
    Returns: kind_of<get-associated-quantity(u)>.
    consteval Unit auto get_unit(AssociatedUnit auto u); +
    Returns: u.
    consteval Unit auto get_common_unit(Unit auto... us) + requires see below; +
    Let +
    • u1 be us...[0],
    • u2 be us...[1],
    • U1 be decltype(u1),
    • U2 be decltype(u2), and
    • rest be a pack denoting the elements of us without u1 and u2.
    Effects: Equivalent to: +if constexpr (sizeof...(us) == 1) + return u1; +else if constexpr (sizeof...(us) == 2) { + if constexpr (is-derived-from-specialization-of<U1, common_unit>()) { + return TBD.; + } else if constexpr (is-derived-from-specialization-of<U2, common_unit>()) + return get_common_unit(u2, u1); + else if constexpr (std::is_same_v<U1, U2>) + return u1; + else if constexpr (equivalent(U1{}, U2{})) { + if constexpr (std::derived_from<U1, typename U2::base-type>) + return u1; + else if constexpr (std::derived_from<U2, typename U1::base-type>) + return u2; + else + return std::conditional_t<type-less-impl<U1, U2>(), U1, U2>{}; + } else { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + + if constexpr (is-positive-integral-power(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is-positive-integral-power(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + if constexpr (type-less<U1, U2>{}) + return common_unit<U1, U2>{}; + else + return common_unit<U2, U1>{}; + } + } +} else + return get_common_unit(get_common_unit(u1, u2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(us) != 0 && (sizeof...(us) == 1 || // + (sizeof...(us) == 2 && convertible(U1{}, U2{})) || + requires { get_common_unit(get_common_unit(u1, u2), rest...); })) +

    5.4.4.9 Associated quantity [assoc.qty]

    template<Unit U> +consteval bool has-associated-quantity(U); // exposition only +
    Returns:
    • If U​::​quantity-spec is a valid expression, +returns true.
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +has-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +let Nums and Dens +be packs denoting the template arguments of +U​::​nums and U​::​dens, respectively.
      Returns +(... && has-associated-quantity(expr-type<Nums>{})) && + (... && has-associated-quantity(expr-type<Dens>{})) +
    • Otherwise, returns false.
    template<AssociatedUnit U> +consteval auto get-associated-quantity(U u); // exposition only +
    Returns:
    • If U is of the form common_unit<Us...>, +returns +get_common_quantity_spec(get-associated-quantity(Us{})...) +
    • Otherwise, if U​::​quantity-spec is a valid expression, +returns +remove-kind(U::quantity-spec) +
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +get-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +returns +expr-map<to-quantity-spec, derived_quantity_spec, struct dimensionless>(u) + +where to-quantity-spec is defined as follows: +template<AssociatedUnit U> +using to-quantity-spec = decltype(get-associated-quantity(U{})); // exposition only +

    5.4.4.10 Symbol formatting [qty.unit.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); +
    Effects: Equivalent to: +TBD. +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.mag.concepts.html b/HEAD/api_reference/gen/qty.unit.mag.concepts.html new file mode 100644 index 00000000..b6eebc0c --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.mag.concepts.html @@ -0,0 +1,9 @@ +[qty.unit.mag.concepts]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.2 Concepts [qty.unit.mag.concepts]

    template<typename T> +concept MagConstant = SymbolicConstant<T> && is-derived-from-specialization-of<T, mag_constant>(); + +template<typename T> +concept UnitMagnitude = (is-specialization-of<T, unit-magnitude>()); + +template<typename T> +concept MagArg = std::integral<T> || MagConstant<T>; // exposition only +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.mag.general.html b/HEAD/api_reference/gen/qty.unit.mag.general.html new file mode 100644 index 00000000..bf2dce47 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.mag.general.html @@ -0,0 +1,3 @@ +[qty.unit.mag.general]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.1 General [qty.unit.mag.general]

    Subclause [qty.unit.mag] specifies the components +used to represent the numerical value (IEC 60050, 112-01-29) of a unit +with support for powers (IEC 60050, 102-02-08) of real numbers (IEC 60050, 102-02-05).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.mag.html b/HEAD/api_reference/gen/qty.unit.mag.html new file mode 100644 index 00000000..cabf2955 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.mag.html @@ -0,0 +1,83 @@ +[qty.unit.mag]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.1 General [qty.unit.mag.general]

    Subclause [qty.unit.mag] specifies the components +used to represent the numerical value (IEC 60050, 112-01-29) of a unit +with support for powers (IEC 60050, 102-02-08) of real numbers (IEC 60050, 102-02-05).

    5.4.4.2.2 Concepts [qty.unit.mag.concepts]

    template<typename T> +concept MagConstant = SymbolicConstant<T> && is-derived-from-specialization-of<T, mag_constant>(); + +template<typename T> +concept UnitMagnitude = (is-specialization-of<T, unit-magnitude>()); + +template<typename T> +concept MagArg = std::integral<T> || MagConstant<T>; // exposition only +

    5.4.4.2.3 Types [qty.unit.mag.types]

    namespace mp_units { + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant { + static constexpr auto symbol = Symbol; // exposition only + static constexpr long double value = Value; // exposition only +}; + +} +
    A specialization of mag_constant represents a real number (IEC 60050, 102-02-05).
    Symbol is its symbol, and +Value is (an approximation of) its value.
    namespace mp_units { + +template<auto... Ms> +struct unit-magnitude { // exposition only + // [qty.unit.mag.ops], operations + + template<UnitMagnitude M> + friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); + + friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); + + template<UnitMagnitude Rhs> + friend consteval bool operator==(unit-magnitude, Rhs); + + template<int Num, int Den = 1> + friend consteval auto pow(unit-magnitude); // exposition only + + // [qty.unit.mag.utils], utilities + + friend consteval bool is-positive-integral-power(unit-magnitude); // exposition only + + template<auto... Ms2> + friend consteval auto common-magnitude(unit-magnitude, // exposition only + unit-magnitude<Ms2...>); +}; + +} +
    A specialization of unit-magnitude +represents the product of its template arguments.
    For the purposes of specifying the implementation-defined limits, +let the representation of the terms of unit-magnitude be the structure +struct { + ratio exp; + base-type base; +}; + +representing the number , +where base-type is a model of MagArg.
    • There is a single term for each base-type.
    • exp.num is not expanded into base.
      [Note 1: 
      is not permitted.
      — end note]
    • exp.den can reduce the base.
      [Note 2: 
      is permitted.
      — end note]
    • If the result of an operation on std​::​intmax_t values is undefined, +the behavior is +implementation-defined.

    5.4.4.2.4 Operations [qty.unit.mag.ops]

    template<UnitMagnitude M> +friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); +
    Returns:
    • If sizeof...(Ms) == 0 is true, returns rhs.
    • Otherwise, if std​::​is_same_v<M, unit-magnitude<>>, returns lhs.
    • Otherwise, returns an unspecified value equal to lhs ×rhs.
    friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); +
    Returns: lhs * pow<-1>(rhs).
    template<UnitMagnitude Rhs> +friend consteval bool operator==(unit-magnitude, Rhs); +
    Returns: std​::​is_same_v<unit-magnitude, Rhs>.
    template<int Num, int Den = 1> +friend consteval auto pow(unit-magnitude base); // exposition only +
    Returns:
    • If Num == 0 is true, returns unit-magnitude<>{}.
    • Otherwise, returns an unspecified value equal to .
    template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; +
    Constraints: V is greater than 0.
    Effects: If MagConstant<decltype(V)> is satisfied, +initializes mag with unit-magnitude<V>{}.
    Otherwise, initializes mag with +an unspecified value equal to V.
    template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; +
    Effects: Initializes mag_ratio with +an unspecified value equal to .
    template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = pow<Num, Den>(mag<Base>); +
    Constraints: Base is greater than 0.

    5.4.4.2.5 Utilities [qty.unit.mag.utils]

    friend consteval bool is-positive-integral-power(unit-magnitude x); // exposition only +
    Returns: false if x has a negative or rational exponent, and +true otherwise.
    template<auto... Ms2> +friend consteval auto common-magnitude(unit-magnitude, unit-magnitude<Ms2...>); // exposition only +
    Returns: The largest magnitude C +such that each input magnitude is expressible +by only positive powers relative to C.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.mag.ops.html b/HEAD/api_reference/gen/qty.unit.mag.ops.html new file mode 100644 index 00000000..46888a60 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.mag.ops.html @@ -0,0 +1,18 @@ +[qty.unit.mag.ops]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.4 Operations [qty.unit.mag.ops]

    template<UnitMagnitude M> +friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); +
    Returns:
    • If sizeof...(Ms) == 0 is true, returns rhs.
    • Otherwise, if std​::​is_same_v<M, unit-magnitude<>>, returns lhs.
    • Otherwise, returns an unspecified value equal to lhs ×rhs.
    friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); +
    Returns: lhs * pow<-1>(rhs).
    template<UnitMagnitude Rhs> +friend consteval bool operator==(unit-magnitude, Rhs); +
    Returns: std​::​is_same_v<unit-magnitude, Rhs>.
    template<int Num, int Den = 1> +friend consteval auto pow(unit-magnitude base); // exposition only +
    Returns:
    • If Num == 0 is true, returns unit-magnitude<>{}.
    • Otherwise, returns an unspecified value equal to .
    template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; +
    Constraints: V is greater than 0.
    Effects: If MagConstant<decltype(V)> is satisfied, +initializes mag with unit-magnitude<V>{}.
    Otherwise, initializes mag with +an unspecified value equal to V.
    template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; +
    Effects: Initializes mag_ratio with +an unspecified value equal to .
    template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = pow<Num, Den>(mag<Base>); +
    Constraints: Base is greater than 0.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.mag.types.html b/HEAD/api_reference/gen/qty.unit.mag.types.html new file mode 100644 index 00000000..cba66dd3 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.mag.types.html @@ -0,0 +1,50 @@ +[qty.unit.mag.types]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.3 Types [qty.unit.mag.types]

    namespace mp_units { + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant { + static constexpr auto symbol = Symbol; // exposition only + static constexpr long double value = Value; // exposition only +}; + +} +
    A specialization of mag_constant represents a real number (IEC 60050, 102-02-05).
    Symbol is its symbol, and +Value is (an approximation of) its value.
    namespace mp_units { + +template<auto... Ms> +struct unit-magnitude { // exposition only + // [qty.unit.mag.ops], operations + + template<UnitMagnitude M> + friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); + + friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); + + template<UnitMagnitude Rhs> + friend consteval bool operator==(unit-magnitude, Rhs); + + template<int Num, int Den = 1> + friend consteval auto pow(unit-magnitude); // exposition only + + // [qty.unit.mag.utils], utilities + + friend consteval bool is-positive-integral-power(unit-magnitude); // exposition only + + template<auto... Ms2> + friend consteval auto common-magnitude(unit-magnitude, // exposition only + unit-magnitude<Ms2...>); +}; + +} +
    A specialization of unit-magnitude +represents the product of its template arguments.
    For the purposes of specifying the implementation-defined limits, +let the representation of the terms of unit-magnitude be the structure +struct { + ratio exp; + base-type base; +}; + +representing the number , +where base-type is a model of MagArg.
    • There is a single term for each base-type.
    • exp.num is not expanded into base.
      [Note 1: 
      is not permitted.
      — end note]
    • exp.den can reduce the base.
      [Note 2: 
      is permitted.
      — end note]
    • If the result of an operation on std​::​intmax_t values is undefined, +the behavior is +implementation-defined.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.mag.utils.html b/HEAD/api_reference/gen/qty.unit.mag.utils.html new file mode 100644 index 00000000..242d3c9f --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.mag.utils.html @@ -0,0 +1,7 @@ +[qty.unit.mag.utils]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.5 Utilities [qty.unit.mag.utils]

    friend consteval bool is-positive-integral-power(unit-magnitude x); // exposition only +
    Returns: false if x has a negative or rational exponent, and +true otherwise.
    template<auto... Ms2> +friend consteval auto common-magnitude(unit-magnitude, unit-magnitude<Ms2...>); // exposition only +
    Returns: The largest magnitude C +such that each input magnitude is expressible +by only positive powers relative to C.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.obs.html b/HEAD/api_reference/gen/qty.unit.obs.html new file mode 100644 index 00000000..d43f5161 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.obs.html @@ -0,0 +1,44 @@ +[qty.unit.obs]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.8 Observers [qty.unit.obs]

    consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +
    Returns: kind_of<get-associated-quantity(u)>.
    consteval Unit auto get_unit(AssociatedUnit auto u); +
    Returns: u.
    consteval Unit auto get_common_unit(Unit auto... us) + requires see below; +
    Let +
    • u1 be us...[0],
    • u2 be us...[1],
    • U1 be decltype(u1),
    • U2 be decltype(u2), and
    • rest be a pack denoting the elements of us without u1 and u2.
    Effects: Equivalent to: +if constexpr (sizeof...(us) == 1) + return u1; +else if constexpr (sizeof...(us) == 2) { + if constexpr (is-derived-from-specialization-of<U1, common_unit>()) { + return TBD.; + } else if constexpr (is-derived-from-specialization-of<U2, common_unit>()) + return get_common_unit(u2, u1); + else if constexpr (std::is_same_v<U1, U2>) + return u1; + else if constexpr (equivalent(U1{}, U2{})) { + if constexpr (std::derived_from<U1, typename U2::base-type>) + return u1; + else if constexpr (std::derived_from<U2, typename U1::base-type>) + return u2; + else + return std::conditional_t<type-less-impl<U1, U2>(), U1, U2>{}; + } else { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + + if constexpr (is-positive-integral-power(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is-positive-integral-power(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + if constexpr (type-less<U1, U2>{}) + return common_unit<U1, U2>{}; + else + return common_unit<U2, U1>{}; + } + } +} else + return get_common_unit(get_common_unit(u1, u2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(us) != 0 && (sizeof...(us) == 1 || // + (sizeof...(us) == 2 && convertible(U1{}, U2{})) || + requires { get_common_unit(get_common_unit(u1, u2), rest...); })) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.one.html b/HEAD/api_reference/gen/qty.unit.one.html new file mode 100644 index 00000000..0a1df4be --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.one.html @@ -0,0 +1,6 @@ +[qty.unit.one]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.7 One [qty.unit.one]

    namespace mp_units { + +struct one final : derived-unit-impl<> {}; + +} +
    one represents the base unit (IEC 60050, 112-01-18) of a quantity of dimension one (IEC 60050, 112-01-13).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.ops.html b/HEAD/api_reference/gen/qty.unit.ops.html new file mode 100644 index 00000000..ba467398 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.ops.html @@ -0,0 +1,55 @@ +[qty.unit.ops]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.6 Operations [qty.unit.ops]

    namespace mp_units { + +struct unit-interface { // exposition only + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator*(M, U u); + + friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; + + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator/(M mag, U u); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); + + // [qty.unit.cmp], comparison + + template<Unit Lhs, Unit Rhs> + friend consteval bool operator==(Lhs, Rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval bool equivalent(Lhs lhs, Rhs rhs); +}; + +} +
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator*(M, U u); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<M, decltype(auto(mag<1>))>) + return u; +else if constexpr (is-specialization-of<U, scaled_unit>()) { + if constexpr (M{} * U::mag == mag<1>) + return U::reference-unit; + else + return scaled_unit<M{} * U::mag, decltype(auto(U::reference-unit))>{}; +} else + return scaled_unit<M{}, U>{}; +
    friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; +
    Recommended practice: Suggest swapping the operands.
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator/(M mag, U u); +
    Returns: mag * inverse(u).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); +
    Returns: expr-multiply<derived_unit, struct one>(lhs, rhs).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); +
    Returns: expr-divide<derived_unit, struct one>(lhs, rhs).
    consteval Unit auto inverse(Unit auto u); +
    Returns: one / u.
    template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires(Den != 0) +consteval Unit auto pow(U u); +
    Returns: expr-pow<Num, Den, derived_unit, struct one>(u).
    consteval Unit auto sqrt(Unit auto u); +
    Returns: pow<1, 2>(u).
    consteval Unit auto cbrt(Unit auto u); +
    Returns: pow<1, 3>(u).
    consteval Unit auto square(Unit auto u); +
    Returns: pow<2>(u).
    consteval Unit auto cubic(Unit auto u); +
    Returns: pow<3>(u).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.sym.fmt.html b/HEAD/api_reference/gen/qty.unit.sym.fmt.html new file mode 100644 index 00000000..632e6227 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.sym.fmt.html @@ -0,0 +1,7 @@ +[qty.unit.sym.fmt]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.10 Symbol formatting [qty.unit.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); +
    Effects: Equivalent to: +TBD. +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.traits.html b/HEAD/api_reference/gen/qty.unit.traits.html new file mode 100644 index 00000000..7371ea55 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.traits.html @@ -0,0 +1,8 @@ +[qty.unit.traits]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.3 Traits [qty.unit.traits]

    template<Unit auto U> +constexpr bool space_before_unit_symbol = true; +
    The formatting functions ([qty.unit.sym.fmt]) use space_before_unit_symbol +to determine whether there is a space +between the numerical value and the unit symbol.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize space_before_unit_symbol +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.unit.types.html b/HEAD/api_reference/gen/qty.unit.types.html new file mode 100644 index 00000000..018187b2 --- /dev/null +++ b/HEAD/api_reference/gen/qty.unit.types.html @@ -0,0 +1,187 @@ +[qty.unit.types]

    5 Quantities and units library [quantities]

    5.4 Reference [qty.ref]

    5.4.4 Unit [qty.unit]

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.1 Canonical [qty.canon.unit]

    namespace mp_units { + +template<UnitMagnitude M, Unit U> +struct canonical-unit { // exposition only + M mag; + U reference_unit; +}; + +} +
    canonical-unit represents a unit expressed in terms of base units (IEC 60050, 112-01-18).
    [Note 1: 
    Other types representing units are equal only if they have the same type.
    canonical-unit is used to implement binary relations other than equality.
    — end note]
    reference_unit is simplified ([qty.sym.expr.algos]).
    consteval auto get-canonical-unit(Unit auto u); // exposition only +
    Returns: The instantiation of canonical-unit for u.

    5.4.4.5.2 Scaled [qty.scaled.unit]

    namespace mp_units { + +template<UnitMagnitude auto M, Unit U> + requires(M != unit-magnitude<>{} && M != mag<1>) +struct scaled_unit final : unit-interface { + using base-type = scaled_unit; // exposition only + static constexpr UnitMagnitude auto mag = M; // exposition only + static constexpr U reference-unit{}; // exposition only + static constexpr auto point-origin = U::point_origin; // exposition only, present only + // if the qualified-id U​::​point_origin is valid and denotes an object +}; + +} +
    scaled_unit<M, U> is used by the library +to represent the unit M ×U.

    5.4.4.5.3 Named [qty.named.unit]

    namespace mp_units { + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS, PO> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol> + requires(!Symbol.empty()) +struct named_unit<Symbol> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U> + requires(!Symbol.empty()) +struct named_unit<Symbol, U> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires(!Symbol.empty()) +struct named_unit<Symbol, U, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +} +
    A named unit is a type that models PrefixableUnit.
    A specialization of named_unit is used as a base type when defining a named unit.
    In the following descriptions, let U be a named unit defined with an alluded signature.
    The identifier of U represents +its unit name (IEC 60050, 112-01-15) +or special unit name (IEC 60050, 112-01-16).
    Symbol is its unit symbol (IEC 60050, 112-01-17).
    The possible arguments to named_unit are +
    • ,
    • ,
    • , and
    • .
    The first signature defines the unit of a base quantity +without a unit prefix (IEC 60050, 112-01-26).
    The second signature defines a unit +that can be reused by several base quantities.
    The third and fourth signatures with a unit expression argument E +define U as implicitly convertible from E.
    The first and fourth signatures with a kind of quantity (IEC 60050, 112-01-04) Q +also restrict U to Q.
    A point origin argument specifies the default point origin of U ([qty.pt.syn]).
    [Example 1: // 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; // . + +// The fourth signature also further restricts the kind of quantity. +inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { +} hertz; // Hz can't measure becquerel, activity, + // or any other quantity with dimension + // that isn't a kind of frequency. + — end example]

    5.4.4.5.4 Prefixed [qty.prefixed.unit]

    namespace mp_units { + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires(!Symbol.empty()) +struct prefixed_unit : decltype(M * U)::base-type { + using base-type = prefixed_unit; // exposition only + static constexpr auto symbol = Symbol + U.symbol; // exposition only +}; + +} +
    prefixed_unit<Symbol, M, U> represents the unit U with a unit prefix (IEC 60050, 112-01-26).
    Symbol is the symbol of the unit prefix.
    M is the factor of the unit prefix.
    A specialization of prefixed_unit is used as a base type when defining a unit prefix.
    [Example 1: template<PrefixableUnit auto U> +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + +template<PrefixableUnit auto U> +constexpr kilo_<U> kilo; + +inline constexpr auto kilogram = kilo<si::gram>; + — end example]

    5.4.4.5.5 Common [qty.common.unit]

    namespace mp_units { + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit final : decltype(get-common-scaled-unit(U1{}, U2{}, Rest{}...))::base-type +{ + using base-type = common_unit; // exposition only + static constexpr auto common-unit = // exposition only + get-common-scaled-unit(U1{}, U2{}, Rest{}...); +}; + +} +
    common_unit is used by the library +to encapsulate a conversion factor between units (IEC 60050, 112-01-33) +common to the operands of quantity addition.
    [Example 1: 
    The result of 1 * km + 1 * mi +has a common unit +encapsulated by common_unit<mi, km>.
    — end example]
    +A program that instantiates a specialization of common_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    template<Unit U1, Unit U2, Unit... Rest> +consteval Unit auto get-common-scaled-unit(U1, U2, Rest... rest) // exposition only + requires see below; +
    Effects: Equivalent to: +constexpr auto res = [] { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + constexpr auto common_mag = common-magnitude(canonical_lhs.mag, canonical_rhs.mag); + if constexpr (common_mag == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit<common_mag, decltype(auto(canonical_lhs.reference_unit))>{}; +}(); +if constexpr (sizeof...(rest) == 0) + return res; +else + return get-common-scaled-unit(res, rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(U1{}, U2{}) && (sizeof...(Rest) == 0 || requires { + get-common-scaled-unit(get-common-scaled-unit(u1, u2), rest...); + })) +

    5.4.4.5.6 Derived [qty.derived.unit]

    namespace mp_units { + +template<typename... Expr> +struct derived-unit-impl : // exposition only + unit-interface, + expr-fractions<struct one, Expr...> { + using base-type = derived-unit-impl; // exposition only +}; + +template<SymbolicConstant... Expr> +struct derived_unit final : derived-unit-impl<Expr...> {}; + +} +
    derived_unit is used by the library +to represent a derived unit (IEC 60050, 112-01-19).
    [Example 1: using namespace si::unit_symbols; +int x = m * m; // error: cannot construct from derived_unit<power<si​::​metre, 2>> +int y = m * s; // error: cannot construct from derived_unit<si​::​metre, si​::​second> +int z = m / s; // error: cannot construct from derived_unit<si​::​metre, per<si​::​second>> + — end example]
    +A program that instantiates a specialization of derived_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.

    5.4.4.5.7 One [qty.unit.one]

    namespace mp_units { + +struct one final : derived-unit-impl<> {}; + +} +
    one represents the base unit (IEC 60050, 112-01-18) of a quantity of dimension one (IEC 60050, 112-01-13).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.utils.html b/HEAD/api_reference/gen/qty.utils.html new file mode 100644 index 00000000..cd5e2f9e --- /dev/null +++ b/HEAD/api_reference/gen/qty.utils.html @@ -0,0 +1,257 @@ +[qty.utils]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.1 Non-types [qty.utils.non.types]

    template<typename T, template<see below> typename U> +consteval bool is-specialization-of(); // exposition only +template<typename T, template<see below> typename U> +consteval bool is-derived-from-specialization-of(); // exposition only +
    Returns:
    • For the first signature, +true of T is a specialization of U, and +false otherwise.
    • For the second signature, +true if T has exactly one public base class +that is a specialization of U +and has no other base class that is a specialization of U, and +false otherwise.
    Remarks: An implementation provides enough overloads for all arguments to U.

    5.3.2 Ratio [qty.ratio]

    namespace mp_units { + +struct ratio { // exposition only + std::intmax_t num; + std::intmax_t den; + + consteval ratio(std::intmax_t n, std::intmax_t d = 1); + + friend consteval bool operator==(ratio, ratio) = default; + friend consteval auto operator<=>(ratio lhs, ratio rhs) { return (lhs - rhs).num <=> 0; } + + friend consteval ratio operator-(ratio r) { return {-r.num, r.den}; } + + friend consteval ratio operator+(ratio lhs, ratio rhs) + { + return {lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den}; + } + + friend consteval ratio operator-(ratio lhs, ratio rhs) { return lhs + (-rhs); } + + friend consteval ratio operator*(ratio lhs, ratio rhs); + + friend consteval ratio operator/(ratio lhs, ratio rhs) + { + return lhs * ratio{rhs.den, rhs.num}; + } +}; + +consteval bool is-integral(ratio r) { return r.num % r.den == 0; } + +consteval ratio common-ratio(ratio r1, ratio r2); + +} +
    ratio represents the rational number .
    Unless otherwise specified, +in the following descriptions, +let R(r) be std​::​ratio<N, D>, +where N and D are the values of r.num and r.den.
    consteval ratio(std::intmax_t n, std::intmax_t d = 1); +
    Let N and D be the values of n and d.
    Let R be std​::​ratio<N, D>.
    Effects: Equivalent to +R.
    Postconditions: num == R​::​num && den == R​::​den is true.
    friend consteval ratio operator*(ratio lhs, ratio rhs); +
    Let Res be std​::​ratio_multiply<R(lhs), R(rhs)>.
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};
    consteval ratio common-ratio(ratio r1, ratio r2); +
    Let Res be equal to +std::common_type<std::chrono::duration<int, R(r1)>, + std::chrono::duration<int, R(r2)>>::type::period +
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};

    5.3.3 Symbol text [qty.sym.txt]

    namespace mp_units { + +template<std::size_t N, std::size_t M> +class symbol_text { +public: + std::fixed_u8string<N> utf8; // exposition only + std::fixed_string<M> portable; // exposition only + + // constructors + constexpr symbol_text(char portable); + consteval symbol_text(const char (&portable)[N + 1]); + constexpr symbol_text(const std::fixed_string<N>& portable); + consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); + constexpr symbol_text(const std::fixed_u8string<N>& utf8, + const std::fixed_string<M>& portable); + + // observers + constexpr const auto& utf8() const { return utf8; } + constexpr const auto& portable() const { return portable; } + constexpr bool empty() const { return utf8().empty(); } + + // string operations + template<std::size_t N2, std::size_t M2> + friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); + + // comparison + template<std::size_t N2, std::size_t M2> + friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; + template<std::size_t N2, std::size_t M2> + friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +}; + +symbol_text(char) -> symbol_text<1, 1>; + +template<std::size_t N> +symbol_text(const char (&)[N]) -> symbol_text<N - 1, N - 1>; + +template<std::size_t N> +symbol_text(const std::fixed_string<N>&) -> symbol_text<N, N>; + +template<std::size_t N, std::size_t M> +symbol_text(const char8_t (&)[N], const char (&)[M]) -> symbol_text<N - 1, M - 1>; + +template<std::size_t N, std::size_t M> +symbol_text(const std::fixed_u8string<N>&, const std::fixed_string<M>&) -> symbol_text<N, M>; + +} +
    symbol_text represents a symbol text.
    utf8 stores its UTF-8 representation, and +portable stores its portable representation.
    symbol_text<N, M> is a structural type (N4971, [temp.param]).
    In the descriptions that follow, +it is a Precondition that +
    • values of char are in the basic literal character set (N4971, [lex.charset]), and
    • for a parameter of the form const CharT (&txt)[M], +(txt[M - 1] == CharT()) is true.
    constexpr symbol_text(char portable); +consteval symbol_text(const char (&portable)[N + 1]); +constexpr symbol_text(const std::fixed_string<N>& portable); +consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); +constexpr symbol_text(const std::fixed_u8string<N>& utf8, const std::fixed_string<M>& portable); +
    For the constructors without a parameter named utf8, +let utf8 be: +std::bit_cast<std::fixed_u8string<N>>(std::basic_fixed_string(portable)) +
    Effects: Equivalent to the mem-initializer-list: +utf8{utf8}, portable{portable} +
    template<std::size_t N2, std::size_t M2> +friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); +
    Effects: Equivalent to: +return symbol_text<N + N2, M + M2>(lhs.utf8() + rhs.utf8(), + lhs.portable() + rhs.portable()); +
    template<std::size_t N2, std::size_t M2> +friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +template<std::size_t N2, std::size_t M2> +friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +
    Let @ be the operator.
    Effects: Equivalent to: +return std::make_tuple(std::cref(lhs.utf8()), std::cref(lhs.portable())) @ + std::make_tuple(std::cref(rhs.utf8()), std::cref(rhs.portable())); +

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.1 General [qty.sym.expr.general]

    Subclause [qty.sym.expr] specifies the components +used to maintain ordered, simplified, and readable +argument lists in the names of specializations.
    [Example 1: using namespace si::unit_symbols; +int x = kg * km / square(h); // error: cannot construct from + // derived_unit<si​::​kilo_<si​::​gram>, si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>> +
    +The library ensures decltype(kg * km / square(h)) is styled-like as commented in diagnostics, +provided that, in the implementation-defined total order of types, +decltype(kg) is less than decltype(km).
    — end example]

    5.3.4.2 Concept SymbolicConstant [qty.sym.expr.concepts]

    template<typename T> +concept SymbolicConstant = // exposition only + std::is_empty_v<T> && std::is_final_v<T> && std::is_trivially_default_constructible_v<T> && + std::is_trivially_copy_constructible_v<T> && std::is_trivially_move_constructible_v<T> && + std::is_trivially_destructible_v<T>; +
    The concept SymbolicConstant +is used to constrain the types +that are used in symbolic expressions.

    5.3.4.3 Types [qty.sym.expr.types]

    namespace mp_units { + +template<typename T, typename... Ts> +struct per final {}; + +} +
    per is used to store arguments with negative exponents.
    A specialization of per +represents the product of the inverse of its template arguments.
    A program that instantiates a specialization of per +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +template<typename F, int Num, int... Den> + requires see below +struct power final { + using factor = F; // exposition only + static constexpr ratio exponent{Num, Den...}; // exposition only +}; + +} +
    power represents a power (IEC 60050, 102-02-08) +of the form .
    [Note 1: 
    Den is optional to shorten the type name when Den is 1.
    — end note]
    +A program that instantiates a specialization of power +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let r be ratio{Num, Den...}.
    Let is-valid-ratio be +true if r is a valid constant expression, and +false otherwise.
    The expression in the requires-clause is equivalent to: +is-valid-ratio && (r > ratio{0}) && (r != ratio{1}) +

    5.3.4.4 Algorithms [qty.sym.expr.algos]

    template<typename T> +using expr-type = see below; // exposition only +
    expr-type<T> denotes +U if T is of the form power<U, Ints...>, and +T otherwise.
    template<typename T, typename U> +consteval bool type-less-impl(); // exposition only +
    Returns: true if T is less than U +in an implementation-defined total order for types, and +false otherwise.
    template<typename Lhs, typename Rhs> +struct type-less : // exposition only + std::bool_constant<is-specialization-of<Rhs, power>() || + type-less-impl<expr-type<Lhs>, expr-type<Rhs>>()> {}; +
    type-less meets the requirements of +the Pred parameter of the symbolic expression algorithms below.
    template<typename... Ts> +struct type-list {}; // exposition only + +template<typename OneType, typename... Ts> +struct expr-fractions { // exposition only + using num = see below; // exposition only + using den = see below; // exposition only +} +
    expr-fractions divides a symbolic expression to numerator and denominator parts.
    Let EF be a specialization of expr-fractions.
    • If EF is of the form expr-fractions<OneType, Ts..., per<Us...>>, +then +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<Us...>.
    • Otherwise, EF is of the form expr-fractions<OneType, Ts...>, and +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<>.
    The symbolic expression algorithms perform operations on symbolic constants.
    A symbolic constant is a type that is a model of SymbolicConstant.
    [Example 1: 
    The dimension dim_length, the quantity time, and the unit one are symbolic constants.
    — end example]
    +The algorithms also support +powers with a symbolic constant base and a rational exponent, +products thereof, and +fractions thereof.
    template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-multiply(Lhs, Rhs); // exposition only + +template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-divide(Lhs lhs, Rhs rhs); // exposition only + +template<template<typename...> typename To, typename OneType, typename T> +consteval auto expr-invert(T); // exposition only + +template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, + typename OneType, template<typename, typename> typename Pred = type-less, typename T> + requires(Den != 0) +consteval auto expr-pow(T); // exposition only +
    Mandates:
    • OneType is the neutral element (IEC 60050, 102-01-19) of the operation, and
    • Pred is a Cpp17BinaryTypeTrait (N4971, [meta.rqmts]) +with a base characteristic of std​::​bool_constant<B>.
      Pred<T, U> implements a total order for types; +B is true if T is ordered before U, and false otherwise.
    Effects:
    First, inputs to the operations are obtained from the types of the function parameters.
    If the type of a function parameter is: +
    • A specialization of To, +then its input is the product of its template arguments, and +the following also apply.
    • A specialization of per, +then its input is the product of the inverse of its template arguments, and +the following also apply.
    • A specialization of the form power<F, Num>, +then its input is , or +a specialization of the form power<F, Num, Den>, +then its input is , and +the following also applies.
    • Otherwise, the input is the symbolic constant itself.
    [Example 2: 
    Item by item, this algorithm step goes from the C++ parameter type +decltype(km / square(h)), +styled in diagnostics like +derived_unit<si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>, +
    • to decltype(km) ×per<power<decltype(h), 2> (product of To's arguments),
    • to (product of inverse of per's arguments),
    • to (powers as powers),
    • to where and (symbolic substitution) +in the mathematical domain.
    — end example]
    Then, the operation takes place: +
    • expr-multiply multiplies its inputs,
    • expr-divide divides the input of its first parameter by the input of its second parameter,
    • expr-invert divides 1 by its input, and
    • expr-pow raises its input to the .
    Finally, let r be the result of the operation simplified as follows: +
    • All terms are part of the same fraction (if any).
    • There is at most a single term with a given symbolic constant.
    • There are no negative exponents.
    • 1 is only present as r and as a numerator with a denominator not equal to 1.
    [Example 3: 
    Item by item:

    (single fraction)
    (unique symbolic constants)
    (positive exponents)
    (non-redundant 1s)
    — end example]
    Returns: r is mapped to the return type: +
    • If , returns OneType{}.
    • Otherwise, if r is a symbolic constant, returns r.
    • Otherwise, first applies the following mappings to the terms of r: +
      • is mapped to power<x, n, d>, and + is mapped to power<x, n>, and
      • 1 is mapped to OneType{}.
    • Then, a denominator x of r (if any) is mapped to per<x>.
    • Then, sorts r without per (if any) and +the template arguments of per (if any) +according to Pred.
    • Finally, returns To<r>{}, where per (if any) is the last argument.
    Remarks: A valid template argument list for To and per +is formed by interspersing commas between each mapped term.
    If a mapping to std​::​intmax_t is not representable, +the program is ill-formed.
    expr-map maps the contents of one symbolic expression to another resulting in a different type list.
    template<template<typename> typename Proj, template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename T> +consteval auto expr-map(T); // exposition only +
    Let +
    • expr-type-map<U> be +power<Proj<F>, Ints...> if U is of the form power<F, Ints...>, and +Proj<U> otherwise,
    • map-power(u) be +pow<Ints...>(F{}) if decltype(u) is of the form power<F, Ints...>, and +u otherwise, and
    • Nums and Dens +be packs denoting the template arguments of +T​::​nums and T​::​dens, respectively.
    Returns: (OneType{} * ... * map-power(expr-type-map<Nums>{})) / +(OneType{} * ... * map-power(expr-type-map<Dens>{})) +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.utils.non.types.html b/HEAD/api_reference/gen/qty.utils.non.types.html new file mode 100644 index 00000000..9167f9cc --- /dev/null +++ b/HEAD/api_reference/gen/qty.utils.non.types.html @@ -0,0 +1,11 @@ +[qty.utils.non.types]

    5 Quantities and units library [quantities]

    5.3 Utilities [qty.utils]

    5.3.1 Non-types [qty.utils.non.types]

    template<typename T, template<see below> typename U> +consteval bool is-specialization-of(); // exposition only +template<typename T, template<see below> typename U> +consteval bool is-derived-from-specialization-of(); // exposition only +
    Returns:
    • For the first signature, +true of T is a specialization of U, and +false otherwise.
    • For the second signature, +true if T has exactly one public base class +that is a specialization of U +and has no other base class that is a specialization of U, and +false otherwise.
    Remarks: An implementation provides enough overloads for all arguments to U.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.val.cmp.html b/HEAD/api_reference/gen/qty.val.cmp.html new file mode 100644 index 00000000..b0d3b034 --- /dev/null +++ b/HEAD/api_reference/gen/qty.val.cmp.html @@ -0,0 +1,13 @@ +[qty.val.cmp]

    5 Quantities and units library [quantities]

    5.6 Quantity [qty]

    5.6.13 Value comparison [qty.val.cmp]

    friend constexpr bool is_eq_zero(const quantity& q) requires see below; +friend constexpr bool is_neq_zero(const quantity& q) requires see below; +friend constexpr bool is_lt_zero(const quantity& q) requires see below; +friend constexpr bool is_gt_zero(const quantity& q) requires see below; +friend constexpr bool is_lteq_zero(const quantity& q) requires see below; +friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +
    Let is_F_zero be the function name.
    Returns:
    Remarks: Let C be +std​::​equality_comparable_with if F is eq or neq, and +std​::​three_way_comparable_with otherwise.
    The expression in the requires-clause is equivalent to: +requires { + { T::zero() } -> C<quantity>; +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.val.traits.html b/HEAD/api_reference/gen/qty.val.traits.html new file mode 100644 index 00000000..55fdb85a --- /dev/null +++ b/HEAD/api_reference/gen/qty.val.traits.html @@ -0,0 +1,12 @@ +[qty.val.traits]

    5 Quantities and units library [quantities]

    5.5 Representation [qty.rep]

    5.5.2 Traits [qty.rep.traits]

    5.5.2.3 Values [qty.val.traits]

    quantity and quantity_point use representation_values +to construct special values of its representation type.
    namespace mp_units { + +template<typename Rep> +struct representation_values : std::chrono::duration_values<Rep> { + static constexpr Rep one() noexcept; +}; + +} +
    The requirements on std​::​chrono​::​duration_values<Rep> (N4971, [time.traits.duration.values]) +also apply to representation_values<Rep>.
    static constexpr Rep one() noexcept; +
    Returns: Rep(1).
    Remarks: The value returned shall be the neutral element for multiplication (IEC 60050, 102-01-19).
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/qty.zeroth.pt.orig.html b/HEAD/api_reference/gen/qty.zeroth.pt.orig.html new file mode 100644 index 00000000..e767b004 --- /dev/null +++ b/HEAD/api_reference/gen/qty.zeroth.pt.orig.html @@ -0,0 +1,8 @@ +[qty.zeroth.pt.orig]

    5 Quantities and units library [quantities]

    5.7 Quantity point [qty.pt]

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.3 Zeroth [qty.zeroth.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct zeroth_point_origin_ final : absolute_point_origin<QS> {}; + +} +
    zeroth_point_origin_<QS> represents an origin +chosen by convention as the value 0 of the quantity QS.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/quantities.html b/HEAD/api_reference/gen/quantities.html new file mode 100644 index 00000000..0490e8f3 --- /dev/null +++ b/HEAD/api_reference/gen/quantities.html @@ -0,0 +1,3469 @@ +[quantities]

    5 Quantities and units library [quantities]

    5.1 Summary [quantities.summary]

    This Clause describes components for dealing with quantities and units, +as summarized in Table 3.
    Table 3: Quantities and units library summary [tab:quantities.summary]
    Subclause
    Module
    Utilities
    mp_units.core
    Reference
    Representation
    Quantity
    Quantity point
    Systems
    mp_units.systems
    std​::​chrono interoperability
    +
    [Editor's note: +Following the SG16 recommendation at https://lists.isocpp.org/sg16/2024/10/4490.php, +the universal-character-names should be replaced by their UTF-8 code points. +]

    5.2 mp-units module synopses [mp.units.syns]

    5.2.1 Module mp_units synopsis [mp.units.syn]

    export module mp_units; + +export import mp_units.core; +export import mp_units.systems; +

    5.2.2 Module mp_units.core synopsis [mp.units.core.syn]

    // mostly freestanding +export module mp_units.core; + +import std; + +export namespace mp_units { + +// [qty.utils], utilities + +// [qty.sym.txt], symbol text + +enum class character_set : std::int8_t { utf8, portable, default_character_set = utf8 }; + +template<std::size_t N, std::size_t M> +class symbol_text; + +// [qty.sym.expr], symbolic expressions + +// [qty.sym.expr.types], types + +template<typename T, typename... Ts> +struct per; + +template<typename F, int Num, int... Den> + requires see below +struct power; + +// [qty.ref], reference + +// [qty.dim], dimension + +// [qty.dim.concepts], concepts + +template<typename T> +concept Dimension = see below; + +template<typename T, auto D> +concept DimensionOf = see below; + +// [qty.dim.types], types + +template<symbol_text Symbol> +struct base_dimension; + +template<SymbolicConstant... Expr> +struct derived_dimension; + +struct dimension_one; +inline constexpr dimension_one dimension_one{}; + +// [qty.dim.ops], operations + +consteval Dimension auto inverse(Dimension auto d); + +template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +consteval Dimension auto sqrt(Dimension auto d); +consteval Dimension auto cbrt(Dimension auto d); + +// [qty.dim.sym.fmt], symbol formatting + +struct dimension_symbol_formatting { + character_set char_set = character_set::default_character_set; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); + +template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); + +// [qty.spec], quantity specification + +// [qty.spec.concepts], concepts + +template<typename T> +concept QuantitySpec = see below; + +template<typename T, auto QS> +concept QuantitySpecOf = see below; + +// [qty.spec.types], types + +// [named.qty], named + +struct is_kind; +inline constexpr is_kind is_kind{}; + +template<auto...> +struct quantity_spec; // not defined + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...>; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...>; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...>; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<QS, Eq, Args...>; + +// [derived.qty], derived + +template<SymbolicConstant... Expr> +struct derived_quantity_spec; + +// [dimless.qty], base quantity of dimension one + +struct dimensionless; +inline constexpr dimensionless dimensionless{}; + +// [kind.of.qty], kind of + +template<QuantitySpec Q> + requires see below +struct kind_of_; +template<QuantitySpec auto Q> + requires requires { typename kind_of_<decltype(Q)>; } +inline constexpr kind_of_<decltype(Q)> kind_of{}; + +// [qty.spec.ops], operations + +consteval QuantitySpec auto inverse(QuantitySpec auto q); + +template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +consteval QuantitySpec auto sqrt(QuantitySpec auto q); +consteval QuantitySpec auto cbrt(QuantitySpec auto q); + +// [qty.spec.hier.algos], hierarchy algorithms + +// [qty.spec.conv], conversion + +consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); + +// [qty.get.kind], get_kind + +template<QuantitySpec Q> +consteval see below get_kind(Q); + +// [get.common.qty.spec], get_common_quantity_spec + +consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; + +// [qty.unit], unit + +// [qty.unit.mag], magnitude + +// [qty.unit.mag.concepts], concepts + +template<typename T> +concept MagConstant = see below; + +template<typename T> +concept UnitMagnitude = see below; + +// [qty.unit.mag.types], types + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant; + +// [qty.unit.mag.ops], operations + +template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; + +template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; + +template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = see below; + +// constants + +inline constexpr struct pi final : + mag_constant<{u8"\u03C0" /* U+03c0 GREEK SMALL LETTER PI */, "pi"}, + std::numbers::pi_v<long double>> { +} pi; + +inline constexpr auto \u03C0 /* U+03c0 GREEK SMALL LETTER PI */ = pi; + +// [qty.unit.traits], traits + +template<Unit auto U> +constexpr bool space_before_unit_symbol = true; + +template<> +inline constexpr bool space_before_unit_symbol<one> = false; + +// [qty.unit.concepts], concepts + +template<typename T> +concept Unit = see below; + +template<typename T> +concept PrefixableUnit = see below; + +template<typename T> +concept AssociatedUnit = see below; + +template<typename U, auto QS> +concept UnitOf = see below; + +// [qty.unit.types], types + +// [qty.scaled.unit], scaled + +template<UnitMagnitude auto M, Unit U> + requires see below +struct scaled_unit; + +// [qty.named.unit], named + +template<symbol_text Symbol, auto...> +struct named_unit; // not defined + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, QS>; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, QS, PO>; + +template<symbol_text Symbol> + requires see below +struct named_unit<Symbol>; + +template<symbol_text Symbol, Unit auto U> + requires see below +struct named_unit<Symbol, U>; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, PO>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires see below +struct named_unit<Symbol, U, QS>; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires see below +struct named_unit<Symbol, U, QS, PO>; + +// [qty.prefixed.unit], prefixed + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires see below +struct prefixed_unit; + +// [qty.common.unit], common + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit; + +// [qty.derived.unit], derived + +template<SymbolicConstant... Expr> +struct derived_unit; + +// [qty.unit.one], one + +struct one; +inline constexpr one one{}; + +// named derived units of a quantity of dimension one + +inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> { +} percent; + +inline constexpr struct per_mille final : + named_unit<symbol_text{u8"\u2030" /* U+2030 PER MILLE SIGN */, "%o"}, + mag_ratio<1, 1000> * one> { +} per_mille; + +inline constexpr struct parts_per_million final : + named_unit<"ppm", mag_ratio<1, 1'000'000> * one> { +} parts_per_million; + +inline constexpr auto ppm = parts_per_million; + +// [qty.unit.ops], operations + +consteval Unit auto inverse(Unit auto u); + +template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires see below +consteval Unit auto pow(U u); +consteval Unit auto sqrt(Unit auto u); +consteval Unit auto cbrt(Unit auto u); +consteval Unit auto square(Unit auto u); +consteval Unit auto cubic(Unit auto u); + +// [qty.unit.cmp], comparison + +template<Unit From, Unit To> +consteval bool convertible(From from, To to); + +// [qty.unit.obs], observers + +consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +consteval Unit auto get_unit(AssociatedUnit auto u); + +consteval Unit auto get_common_unit(Unit auto... us) + requires see below; + +// [qty.unit.sym.fmt], symbol formatting + +enum class unit_symbol_solidus : std::int8_t { + one_denominator, + always, + never, + default_denominator = one_denominator +}; + +enum class unit_symbol_separator : std::int8_t { + space, + half_high_dot, + default_separator = space +}; + +struct unit_symbol_formatting { + character_set char_set = character_set::default_character_set; + unit_symbol_solidus solidus = unit_symbol_solidus::default_denominator; + unit_symbol_separator separator = unit_symbol_separator::default_separator; +}; + +template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); + +template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); + +// [qty.ref.concepts], concepts + +template<typename T> +concept Reference = see below; + +template<typename T, auto QS> +concept ReferenceOf = see below; + +// [qty.ref.syn], class template reference + +template<QuantitySpec Q, Unit U> +struct reference; + +// [qty.ref.ops], operations + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); + +template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); + +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; + +// [qty.ref.obs], observers + +template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); + +template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); + +consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; + +template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; + +// [qty.rep], representation + +enum class quantity_character { scalar, complex, vector, tensor }; + +// [qty.rep.traits], traits + +// [qty.fp.traits], floating-point + +template<typename Rep> +constexpr bool treat_as_floating_point = see below; + +// [qty.char.traits], quantity character + +template<typename T> +constexpr bool disable_scalar = false; +template<> +inline constexpr bool disable_scalar<bool> = true; +template<typename T> +constexpr bool disable_scalar<std::complex<T>> = true; + +template<typename T> +constexpr bool disable_complex = false; + +template<typename T> +constexpr bool disable_vector = false; + +// [qty.val.traits], values + +template<typename Rep> +struct representation_values; + +// [qty.rep.cpos], customization point objects + +inline namespace unspecified { + +inline constexpr unspecified real = unspecified; +inline constexpr unspecified imag = unspecified; +inline constexpr unspecified modulus = unspecified; + +inline constexpr unspecified magnitude = unspecified; + +} + +// [qty.rep.concepts], concepts + +template<typename T> +concept Representation = see below; + +template<typename T, quantity_character Ch> +concept RepresentationOf = see below; + +// [qty], quantity + +// [qty.like], interoperability + +template<typename T> +struct quantity_like_traits; // not defined + +template<typename T> +concept QuantityLike = see below; + +// [qty.syn], class template quantity + +template<typename T> +concept Quantity = see below; + +template<typename Q, auto QS> +concept QuantityOf = see below; + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity; + +// [qty.delta], construction helper delta + +template<Reference R> +struct delta_; + +template<Reference auto R> +constexpr delta_<decltype(R)> delta{}; + +// [qty.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Representation ToRep, see below> + requires see below +constexpr quantity<see below, ToRep> value_cast(see below q); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr Quantity auto value_cast(see below q); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<Quantity ToQ, see below> + requires see below +constexpr Quantity auto value_cast(see below q); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr Quantity auto quantity_cast(see below q); + +} + +// [qty.common.type], std​::​common_type specializations + +template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires see below +struct std::common_type<Q1, Q2>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires see below +struct std::common_type<Q, Value>; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires requires { typename std::common_type<Q, Value>; } +struct std::common_type<Value, Q> : std::common_type<Q, Value> {}; + +namespace mp_units { + +// [qty.pt], quantity point + +// [qty.pt.orig], point origin + +// [qty.pt.orig.concepts], concepts + +template<typename T> +concept PointOrigin = see below; + +template<typename T, auto QS> +concept PointOriginFor = see below; + +// [qty.pt.orig.types], types + +// [qty.abs.pt.orig], absolute + +template<QuantitySpec auto QS> +struct absolute_point_origin; + +// [qty.rel.pt.orig], relative + +template<QuantityPoint auto QP> +struct relative_point_origin; + +// [qty.zeroth.pt.orig], zeroth + +template<QuantitySpec auto QS> +struct zeroth_point_origin_; + +template<QuantitySpec auto QS> +constexpr zeroth_point_origin_<QS> zeroth_point_origin{}; + +// [qty.def.pt.orig], default + +template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); + +// [qty.pt.like], interoperability + +template<typename T> +struct quantity_point_like_traits; // not defined + +template<typename T> +concept QuantityPointLike = see below; + +// [qty.pt.syn], class template quantity_point + +template<typename T> +concept QuantityPoint = see below; + +template<typename QP, auto V> +concept QuantityPointOf = see below; + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point; + +// [qty.point], construction helper point + +template<Reference R> +struct point_; + +template<Reference auto R> +constexpr point_<decltype(R)> point{}; + +// [qty.pt.non.mem.conv], non-member conversions + +template<Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Representation ToRep, see below> + requires see below +constexpr quantity_point<see below, see below, ToRep> value_cast(see below qp); + +template<Unit auto ToU, Representation ToRep, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); +template<Representation ToRep, Unit auto ToU, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<Quantity ToQ, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantityPoint ToQP, see below> + requires see below +constexpr QuantityPoint auto value_cast(see below qp); + +template<QuantitySpec auto ToQS, see below> + requires see below +constexpr QuantityPoint auto quantity_cast(see below qp); + +} +

    5.2.3 Module mp_units.systems synopsis [mp.units.systems.syn]

    export module mp_units.systems; + +export import mp_units.core; +import std; + +export namespace mp_units { + +// [qty.chrono], std​::​chrono interoperability + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>>; + +template<typename Clock> +struct chrono_point_origin_; +template<typename Clock> +constexpr chrono_point_origin_<Clock> chrono_point_origin{}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>>; + +} +

    5.3 Utilities [qty.utils]

    5.3.1 Non-types [qty.utils.non.types]

    template<typename T, template<see below> typename U> +consteval bool is-specialization-of(); // exposition only +template<typename T, template<see below> typename U> +consteval bool is-derived-from-specialization-of(); // exposition only +
    Returns:
    • For the first signature, +true of T is a specialization of U, and +false otherwise.
    • For the second signature, +true if T has exactly one public base class +that is a specialization of U +and has no other base class that is a specialization of U, and +false otherwise.
    Remarks: An implementation provides enough overloads for all arguments to U.

    5.3.2 Ratio [qty.ratio]

    namespace mp_units { + +struct ratio { // exposition only + std::intmax_t num; + std::intmax_t den; + + consteval ratio(std::intmax_t n, std::intmax_t d = 1); + + friend consteval bool operator==(ratio, ratio) = default; + friend consteval auto operator<=>(ratio lhs, ratio rhs) { return (lhs - rhs).num <=> 0; } + + friend consteval ratio operator-(ratio r) { return {-r.num, r.den}; } + + friend consteval ratio operator+(ratio lhs, ratio rhs) + { + return {lhs.num * rhs.den + lhs.den * rhs.num, lhs.den * rhs.den}; + } + + friend consteval ratio operator-(ratio lhs, ratio rhs) { return lhs + (-rhs); } + + friend consteval ratio operator*(ratio lhs, ratio rhs); + + friend consteval ratio operator/(ratio lhs, ratio rhs) + { + return lhs * ratio{rhs.den, rhs.num}; + } +}; + +consteval bool is-integral(ratio r) { return r.num % r.den == 0; } + +consteval ratio common-ratio(ratio r1, ratio r2); + +} +
    ratio represents the rational number .
    Unless otherwise specified, +in the following descriptions, +let R(r) be std​::​ratio<N, D>, +where N and D are the values of r.num and r.den.
    consteval ratio(std::intmax_t n, std::intmax_t d = 1); +
    Let N and D be the values of n and d.
    Let R be std​::​ratio<N, D>.
    Effects: Equivalent to +R.
    Postconditions: num == R​::​num && den == R​::​den is true.
    friend consteval ratio operator*(ratio lhs, ratio rhs); +
    Let Res be std​::​ratio_multiply<R(lhs), R(rhs)>.
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};
    consteval ratio common-ratio(ratio r1, ratio r2); +
    Let Res be equal to +std::common_type<std::chrono::duration<int, R(r1)>, + std::chrono::duration<int, R(r2)>>::type::period +
    Effects: Equivalent to: +return {Res​::​num, Res​::​den};

    5.3.3 Symbol text [qty.sym.txt]

    namespace mp_units { + +template<std::size_t N, std::size_t M> +class symbol_text { +public: + std::fixed_u8string<N> utf8; // exposition only + std::fixed_string<M> portable; // exposition only + + // constructors + constexpr symbol_text(char portable); + consteval symbol_text(const char (&portable)[N + 1]); + constexpr symbol_text(const std::fixed_string<N>& portable); + consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); + constexpr symbol_text(const std::fixed_u8string<N>& utf8, + const std::fixed_string<M>& portable); + + // observers + constexpr const auto& utf8() const { return utf8; } + constexpr const auto& portable() const { return portable; } + constexpr bool empty() const { return utf8().empty(); } + + // string operations + template<std::size_t N2, std::size_t M2> + friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); + + // comparison + template<std::size_t N2, std::size_t M2> + friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; + template<std::size_t N2, std::size_t M2> + friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +}; + +symbol_text(char) -> symbol_text<1, 1>; + +template<std::size_t N> +symbol_text(const char (&)[N]) -> symbol_text<N - 1, N - 1>; + +template<std::size_t N> +symbol_text(const std::fixed_string<N>&) -> symbol_text<N, N>; + +template<std::size_t N, std::size_t M> +symbol_text(const char8_t (&)[N], const char (&)[M]) -> symbol_text<N - 1, M - 1>; + +template<std::size_t N, std::size_t M> +symbol_text(const std::fixed_u8string<N>&, const std::fixed_string<M>&) -> symbol_text<N, M>; + +} +
    symbol_text represents a symbol text.
    utf8 stores its UTF-8 representation, and +portable stores its portable representation.
    symbol_text<N, M> is a structural type (N4971, [temp.param]).
    In the descriptions that follow, +it is a Precondition that +
    • values of char are in the basic literal character set (N4971, [lex.charset]), and
    • for a parameter of the form const CharT (&txt)[M], +(txt[M - 1] == CharT()) is true.
    constexpr symbol_text(char portable); +consteval symbol_text(const char (&portable)[N + 1]); +constexpr symbol_text(const std::fixed_string<N>& portable); +consteval symbol_text(const char8_t (&utf8)[N + 1], const char (&portable)[M + 1]); +constexpr symbol_text(const std::fixed_u8string<N>& utf8, const std::fixed_string<M>& portable); +
    For the constructors without a parameter named utf8, +let utf8 be: +std::bit_cast<std::fixed_u8string<N>>(std::basic_fixed_string(portable)) +
    Effects: Equivalent to the mem-initializer-list: +utf8{utf8}, portable{portable} +
    template<std::size_t N2, std::size_t M2> +friend constexpr symbol_text<N + N2, M + M2> operator+(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs); +
    Effects: Equivalent to: +return symbol_text<N + N2, M + M2>(lhs.utf8() + rhs.utf8(), + lhs.portable() + rhs.portable()); +
    template<std::size_t N2, std::size_t M2> +friend constexpr bool operator==(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +template<std::size_t N2, std::size_t M2> +friend constexpr auto operator<=>(const symbol_text& lhs, + const symbol_text<N2, M2>& rhs) noexcept; +
    Let @ be the operator.
    Effects: Equivalent to: +return std::make_tuple(std::cref(lhs.utf8()), std::cref(lhs.portable())) @ + std::make_tuple(std::cref(rhs.utf8()), std::cref(rhs.portable())); +

    5.3.4 Symbolic expressions [qty.sym.expr]

    5.3.4.1 General [qty.sym.expr.general]

    Subclause [qty.sym.expr] specifies the components +used to maintain ordered, simplified, and readable +argument lists in the names of specializations.
    [Example 1: using namespace si::unit_symbols; +int x = kg * km / square(h); // error: cannot construct from + // derived_unit<si​::​kilo_<si​::​gram>, si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>> +
    +The library ensures decltype(kg * km / square(h)) is styled-like as commented in diagnostics, +provided that, in the implementation-defined total order of types, +decltype(kg) is less than decltype(km).
    — end example]

    5.3.4.2 Concept SymbolicConstant [qty.sym.expr.concepts]

    template<typename T> +concept SymbolicConstant = // exposition only + std::is_empty_v<T> && std::is_final_v<T> && std::is_trivially_default_constructible_v<T> && + std::is_trivially_copy_constructible_v<T> && std::is_trivially_move_constructible_v<T> && + std::is_trivially_destructible_v<T>; +
    The concept SymbolicConstant +is used to constrain the types +that are used in symbolic expressions.

    5.3.4.3 Types [qty.sym.expr.types]

    namespace mp_units { + +template<typename T, typename... Ts> +struct per final {}; + +} +
    per is used to store arguments with negative exponents.
    A specialization of per +represents the product of the inverse of its template arguments.
    A program that instantiates a specialization of per +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +template<typename F, int Num, int... Den> + requires see below +struct power final { + using factor = F; // exposition only + static constexpr ratio exponent{Num, Den...}; // exposition only +}; + +} +
    power represents a power (IEC 60050, 102-02-08) +of the form .
    [Note 1: 
    Den is optional to shorten the type name when Den is 1.
    — end note]
    +A program that instantiates a specialization of power +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let r be ratio{Num, Den...}.
    Let is-valid-ratio be +true if r is a valid constant expression, and +false otherwise.
    The expression in the requires-clause is equivalent to: +is-valid-ratio && (r > ratio{0}) && (r != ratio{1}) +

    5.3.4.4 Algorithms [qty.sym.expr.algos]

    template<typename T> +using expr-type = see below; // exposition only +
    expr-type<T> denotes +U if T is of the form power<U, Ints...>, and +T otherwise.
    template<typename T, typename U> +consteval bool type-less-impl(); // exposition only +
    Returns: true if T is less than U +in an implementation-defined total order for types, and +false otherwise.
    template<typename Lhs, typename Rhs> +struct type-less : // exposition only + std::bool_constant<is-specialization-of<Rhs, power>() || + type-less-impl<expr-type<Lhs>, expr-type<Rhs>>()> {}; +
    type-less meets the requirements of +the Pred parameter of the symbolic expression algorithms below.
    template<typename... Ts> +struct type-list {}; // exposition only + +template<typename OneType, typename... Ts> +struct expr-fractions { // exposition only + using num = see below; // exposition only + using den = see below; // exposition only +} +
    expr-fractions divides a symbolic expression to numerator and denominator parts.
    Let EF be a specialization of expr-fractions.
    • If EF is of the form expr-fractions<OneType, Ts..., per<Us...>>, +then +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<Us...>.
    • Otherwise, EF is of the form expr-fractions<OneType, Ts...>, and +
      • EF​::​num denotes type-list<Ts...>, and
      • EF​::​den denotes type-list<>.
    The symbolic expression algorithms perform operations on symbolic constants.
    A symbolic constant is a type that is a model of SymbolicConstant.
    [Example 1: 
    The dimension dim_length, the quantity time, and the unit one are symbolic constants.
    — end example]
    +The algorithms also support +powers with a symbolic constant base and a rational exponent, +products thereof, and +fractions thereof.
    template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-multiply(Lhs, Rhs); // exposition only + +template<template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename Lhs, typename Rhs> +consteval auto expr-divide(Lhs lhs, Rhs rhs); // exposition only + +template<template<typename...> typename To, typename OneType, typename T> +consteval auto expr-invert(T); // exposition only + +template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, + typename OneType, template<typename, typename> typename Pred = type-less, typename T> + requires(Den != 0) +consteval auto expr-pow(T); // exposition only +
    Mandates:
    • OneType is the neutral element (IEC 60050, 102-01-19) of the operation, and
    • Pred is a Cpp17BinaryTypeTrait (N4971, [meta.rqmts]) +with a base characteristic of std​::​bool_constant<B>.
      Pred<T, U> implements a total order for types; +B is true if T is ordered before U, and false otherwise.
    Effects:
    First, inputs to the operations are obtained from the types of the function parameters.
    If the type of a function parameter is: +
    • A specialization of To, +then its input is the product of its template arguments, and +the following also apply.
    • A specialization of per, +then its input is the product of the inverse of its template arguments, and +the following also apply.
    • A specialization of the form power<F, Num>, +then its input is , or +a specialization of the form power<F, Num, Den>, +then its input is , and +the following also applies.
    • Otherwise, the input is the symbolic constant itself.
    [Example 2: 
    Item by item, this algorithm step goes from the C++ parameter type +decltype(km / square(h)), +styled in diagnostics like +derived_unit<si​::​kilo_<si​::​metre>, per<power<non_si​::​hour, 2>>, +
    • to decltype(km) ×per<power<decltype(h), 2> (product of To's arguments),
    • to (product of inverse of per's arguments),
    • to (powers as powers),
    • to where and (symbolic substitution) +in the mathematical domain.
    — end example]
    Then, the operation takes place: +
    • expr-multiply multiplies its inputs,
    • expr-divide divides the input of its first parameter by the input of its second parameter,
    • expr-invert divides 1 by its input, and
    • expr-pow raises its input to the .
    Finally, let r be the result of the operation simplified as follows: +
    • All terms are part of the same fraction (if any).
    • There is at most a single term with a given symbolic constant.
    • There are no negative exponents.
    • 1 is only present as r and as a numerator with a denominator not equal to 1.
    [Example 3: 
    Item by item:

    (single fraction)
    (unique symbolic constants)
    (positive exponents)
    (non-redundant 1s)
    — end example]
    Returns: r is mapped to the return type: +
    • If , returns OneType{}.
    • Otherwise, if r is a symbolic constant, returns r.
    • Otherwise, first applies the following mappings to the terms of r: +
      • is mapped to power<x, n, d>, and + is mapped to power<x, n>, and
      • 1 is mapped to OneType{}.
    • Then, a denominator x of r (if any) is mapped to per<x>.
    • Then, sorts r without per (if any) and +the template arguments of per (if any) +according to Pred.
    • Finally, returns To<r>{}, where per (if any) is the last argument.
    Remarks: A valid template argument list for To and per +is formed by interspersing commas between each mapped term.
    If a mapping to std​::​intmax_t is not representable, +the program is ill-formed.
    expr-map maps the contents of one symbolic expression to another resulting in a different type list.
    template<template<typename> typename Proj, template<typename...> typename To, typename OneType, + template<typename, typename> typename Pred = type-less, typename T> +consteval auto expr-map(T); // exposition only +
    Let +
    • expr-type-map<U> be +power<Proj<F>, Ints...> if U is of the form power<F, Ints...>, and +Proj<U> otherwise,
    • map-power(u) be +pow<Ints...>(F{}) if decltype(u) is of the form power<F, Ints...>, and +u otherwise, and
    • Nums and Dens +be packs denoting the template arguments of +T​::​nums and T​::​dens, respectively.
    Returns: (OneType{} * ... * map-power(expr-type-map<Nums>{})) / +(OneType{} * ... * map-power(expr-type-map<Dens>{})) +

    5.4 Reference [qty.ref]

    5.4.1 General [qty.ref.general]

    Subclause [qty.ref] specifies the components +for describing the reference of a quantity (IEC 60050, 112-01-01).

    5.4.2 Dimension [qty.dim]

    5.4.2.1 General [qty.dim.general]

    Subclause [qty.dim] specifies the components +for defining the dimension of a quantity (IEC 60050, 112-01-11).

    5.4.2.2 Concepts [qty.dim.concepts]

    template<typename T> +concept Dimension = SymbolicConstant<T> && std::derived_from<T, dimension-interface>; + +template<typename T> +concept BaseDimension = // exposition only + Dimension<T> && (is-derived-from-specialization-of<T, base_dimension>()); + +template<typename T, auto D> +concept DimensionOf = Dimension<T> && Dimension<decltype(D)> && (T{} == D); +

    5.4.2.3 Types [qty.dim.types]

    namespace mp_units { + +template<symbol_text Symbol> +struct base_dimension : dimension-interface { + static constexpr auto symbol = Symbol; // exposition only +}; + +} +
    base_dimension is used +to define the dimension of a base quantity (IEC 60050, 112-01-08).
    Symbol is its symbolic representation.
    [Example 1: inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length; + — end example]
    namespace mp_units { + +template<typename... Expr> +struct derived-dimension-impl // exposition only + : expr-fractions<struct dimension_one, Expr...> {}; + +template<SymbolicConstant... Expr> +struct derived_dimension final : dimension-interface, derived-dimension-impl<Expr...> {}; + +} +
    derived_dimension is used by the library +to represent the dimension of a derived quantity (IEC 60050, 112-01-10).
    [Example 2: constexpr auto dim_acceleration = isq::speed.dimension / isq::dim_time; +int x = dim_acceleration; // error: cannot construct from + // derived_dimension<isq​::​dim_length, per<power<isq​::​dim_time, 2>>> + — end example]
    +A program that instantiates a specialization of derived_dimension +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    namespace mp_units { + +struct dimension_one final : dimension-interface, derived-dimension-impl<> {}; + +} +
    dimension_one represents the dimension of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.2.4 Operations [qty.dim.ops]

    namespace mp_units { + +struct dimension-interface { // exposition only + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator*(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval Dimension auto operator/(Lhs, Rhs); + + template<Dimension Lhs, Dimension Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator*(Lhs, Rhs); +
    Returns: expr-multiply<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval Dimension auto operator/(Lhs, Rhs); +
    Returns: expr-divide<derived_dimension, struct dimension_one>(Lhs{}, Rhs{}).
    template<Dimension Lhs, Dimension Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval Dimension auto inverse(Dimension auto d); +
    Returns: dimension_one / d.
    template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D> + requires(Den != 0) +consteval Dimension auto pow(D d); +
    Returns: expr-pow<Num, Den, derived_dimension, struct dimension_one>(d).
    consteval Dimension auto sqrt(Dimension auto d); +
    Returns: pow<1, 2>(d).
    consteval Dimension auto cbrt(Dimension auto d); +
    Returns: pow<1, 3>(d).

    5.4.2.5 Symbol formatting [qty.dim.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Dimension D> +constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<dimension_symbol_formatting fmt = {}, typename CharT = char, Dimension D> +consteval std::string_view dimension_symbol(D); +
    Effects: Equivalent to: +TBD. +

    5.4.3 Quantity specification [qty.spec]

    5.4.3.1 General [qty.spec.general]

    Subclause [qty.spec] specifies the components +for defining a quantity (IEC 60050, 112-01-01).

    5.4.3.2 Concepts [qty.spec.concepts]

    template<typename T> +concept QuantitySpec = SymbolicConstant<T> && std::derived_from<T, quantity-spec-interface>; + +template<typename T> +concept QuantityKindSpec = // exposition only + QuantitySpec<T> && is-specialization-of<T, kind_of_>(); + +template<typename T> +concept NamedQuantitySpec = // exposition only + QuantitySpec<T> && is-derived-from-specialization-of<T, quantity_spec>() && + (!QuantityKindSpec<T>); + +template<typename T> +concept DerivedQuantitySpec = // exposition only + QuantitySpec<T> && + (is-specialization-of<T, derived_quantity_spec>() || + (QuantityKindSpec<T> && + is-specialization-of<decltype(auto(T::quantity-spec)), derived_quantity_spec>())); + +template<auto Child, auto Parent> +concept ChildQuantitySpecOf = (is-child-of(Child, Parent)); // exposition only + +template<auto To, auto From> +concept NestedQuantityKindSpecOf = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && + (get_kind(From) != get_kind(To)) && ChildQuantitySpecOf<To, get_kind(From).quantity-spec>; + +template<auto From, auto To> +concept QuantitySpecConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && implicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecExplicitlyConvertibleTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && explicitly_convertible(From, To); + +template<auto From, auto To> +concept QuantitySpecCastableTo = // exposition only + QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && castable(From, To); + +template<typename T, auto QS> +concept QuantitySpecOf = + QuantitySpec<T> && QuantitySpec<decltype(QS)> && QuantitySpecConvertibleTo<T{}, QS> && + !NestedQuantityKindSpecOf<T{}, QS> && + (QuantityKindSpec<T> || !NestedQuantityKindSpecOf<QS, T{}>); + +template<typename T> +concept QSProperty = (!QuantitySpec<T>); // exposition only +

    5.4.3.3 Types [qty.spec.types]

    5.4.3.3.1 Named [named.qty]

    namespace mp_units { + +struct is_kind {}; + +template<BaseDimension auto Dim, QSProperty auto... Args> +struct quantity_spec<Dim, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr BaseDimension auto dimension = Dim; + static constexpr quantity_character character = see below; +}; + +template<DerivedQuantitySpec auto Eq, QSProperty auto... Args> +struct quantity_spec<Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = Eq.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, QSProperty auto... Args> +struct quantity_spec<QS, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = parent.equation; // exposition only, present only + // if the qualified-id parent.equation is valid and denotes an object + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +template<NamedQuantitySpec auto QS, DerivedQuantitySpec auto Eq, QSProperty auto... Args> + requires QuantitySpecExplicitlyConvertibleTo<Eq, QS> +struct quantity_spec<QS, Eq, Args...> : quantity-spec-interface { + using base-type = quantity_spec; + static constexpr auto parent = QS; + static constexpr auto equation = Eq; + static constexpr Dimension auto dimension = parent.dimension; + static constexpr quantity_character character = see below; +}; + +} +
    A named quantity is a type that models NamedQuantitySpec.
    A specialization of quantity_spec is used as a base type when defining a named quantity.
    In the following descriptions, let Q be a named quantity defined with an alluded signature.
    The identifier of Q represents its quantity name (IEC 60050, 112-01-02).
    Let Ch be an enumerator value of quantity_character.
    The possible arguments to quantity_spec are +
    • ,
    • ,
    • , and
    • .
    If the first argument is a base quantity dimension, +then Q is that base quantity (IEC 60050, 112-01-08).
    If an argument is a quantity calculus (IEC 60050, 112-01-30) C, +then Q is implicitly convertible from C.
    If the first argument is a named quantity, +then Q is of its kind (IEC 60050, 112-01-04).
    The member character represents +the set of the numerical value of Q ([qty.char.traits]) +and is equal to +
    • Ch if specified,
    • otherwise, quantity_character​::​scalar for the first signature, and
    • otherwise, (BC).character, +where BC is the argument preceding Ch in the signatures above.
    is_kind specifies Q to start a new hierarchy tree of a kind.
    Optional arguments may appear in any order.
    [Example 1: // The first signature defines a base quantity. +inline constexpr struct length final : quantity_spec<dim_length> { +} length; // Length is a base quantity. + +// The second signature defines a derived quantity. +inline constexpr struct area final : quantity_spec<pow<2>(length)> { +} area; // An area equals length by length. + +// The third and fourth signatures add a leaf to a hierarchy of kinds. +inline constexpr struct width final : quantity_spec<length> { +} width; // Width is a kind of length. + +// The fourth signature also refines the calculus required for implicit conversions. +inline constexpr struct angular_measure final : + quantity_spec<dimensionless, arc_length / radius, is_kind> { +} angular_measure; // Requires an arc length per radius, not just any quantity of dimension one. + — end example]

    5.4.3.3.2 Derived [derived.qty]

    namespace mp_units { + +template<NamedQuantitySpec Q> +using to-dimension = decltype(auto(Q::dimension)); // exposition only + +template<typename... Expr> +struct derived-quantity-spec-impl : // exposition only + quantity-spec-interface, + expr-fractions<struct dimensionless, Expr...> { + using base-type = derived-quantity-spec-impl; + using base = expr-fractions<struct dimensionless, Expr...>; + + static constexpr Dimension auto dimension = + expr-map<to-dimension, derived_dimension, struct dimension_one>(base{}); + static constexpr quantity_character character = see below; +}; + +template<SymbolicConstant... Expr> +struct derived_quantity_spec final : derived-quantity-spec-impl<Expr...> {}; + +} +
    derived_quantity_spec is used by the library +to represent the result of a quantity calculus not equal to a named quantity.
    [Example 1: constexpr auto area = pow<2>(isq::length); +int x = area; // error: cannot construct from derived_quantity_spec<power<isq​::​length, 2>> + — end example]
    +A program that instantiates a specialization of derived_quantity_spec +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    Let +
    • Nums and Dens +be packs denoting the template arguments of +base​::​nums and base​::​dens, respectively,
    • QUANTITY-CHARACTER-OF(Pack) be +std::max({quantity_character::scalar, expr-type<Pack>::character...}) + +and
    • num_char be QUANTITY-CHARACTER-OF(Nums) and +den_char be QUANTITY-CHARACTER-OF(Dens).
    +The member character is equal to +quantity_character​::​scalar if num_char == den_char is true, and +std​::​max(num_char, den_char) otherwise.

    5.4.3.3.3 Base quantity of dimension one [dimless.qty]

    namespace mp_units { + +struct dimensionless final : quantity_spec<derived_quantity_spec<>> {}; + +} +
    dimensionless represents the base quantity of dimension one (IEC 60050, 112-01-13).

    5.4.3.3.4 Kind of [kind.of.qty]

    namespace mp_units { + +template<QuantitySpec Q> + requires(!QuantityKindSpec<Q>) && (get-kind-tree-root(Q{}) == Q{}) +struct kind_of_ final : Q::base-type { + using base-type = kind_of_; // exposition only + static constexpr auto quantity-spec = Q{}; // exposition only +}; + +} +
    kind_of<Q> represents a kind of quantity (IEC 60050, 112-01-04) Q.

    5.4.3.4 Utilities [qty.spec.utils]

    template<QuantitySpec auto... From, QuantitySpec Q> +consteval QuantitySpec auto clone-kind-of(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr ((... && QuantityKindSpec<decltype(From)>)) + return kind_of<Q{}>; +else + return q; +
    template<QuantitySpec Q> +consteval auto remove-kind(Q q); // exposition only +
    Effects: Equivalent to: +if constexpr (QuantityKindSpec<Q>) + return Q::quantity-spec; +else + return q; +
    template<QuantitySpec QS, Unit U> + requires(!AssociatedUnit<U>) || UnitOf<U, QS{}> +consteval Reference auto make-reference(QS, U u); // exposition only +
    Effects: Equivalent to: +if constexpr (requires { requires get_quantity_spec(U{}) == QS{}; }) + return u; +else + return reference<QS, U>{}; +

    5.4.3.5 Operations [qty.spec.ops]

    namespace mp_units { + +struct quantity-spec-interface { // exposition only + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); + + template<typename Self, UnitOf<Self{}> U> + consteval Reference auto operator[](this Self self, U u); + + template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> + constexpr Quantity auto operator()(this Self self, FwdQ&& q); + + template<QuantitySpec Lhs, QuantitySpec Rhs> + friend consteval bool operator==(Lhs, Rhs); +}; + +} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-multiply<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs); +
    Returns: clone-kind-of<Lhs{}, Rhs{}>(expr-divide<derived_quantity_spec, struct dimensionless>( + remove-kind(lhs), remove-kind(rhs))) +
    template<typename Self, UnitOf<Self{}> U> +consteval Reference auto operator[](this Self self, U u); +
    Returns: make-reference(self, u).
    template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}> +constexpr Quantity auto operator()(this Self self, FwdQ&& q); +
    Returns: quantity{std::forward<FwdQ>(q).numerical-value, make-reference(self, Q::unit)} +
    template<QuantitySpec Lhs, QuantitySpec Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    consteval QuantitySpec auto inverse(QuantitySpec auto q); +
    Returns: dimensionless / q.
    template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q> + requires(Den != 0) +consteval QuantitySpec auto pow(Q q); +
    Returns: clone-kind-of<Q{}>( + expr-pow<Num, Den, derived_quantity_spec, struct dimensionless>(remove-kind(q))); +
    consteval QuantitySpec auto sqrt(QuantitySpec auto q); +
    Returns: pow<1, 2>(q).
    consteval QuantitySpec auto cbrt(QuantitySpec auto q); +
    Returns: pow<1, 3>(q).

    5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

    5.4.3.6.1 Conversion [qty.spec.conv]

    consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool castable(QuantitySpec auto from, QuantitySpec auto to); +
    Returns: TBD.
    consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2); +
    Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).

    5.4.3.6.2 Get kind [qty.get.kind]

    template<QuantitySpec Q> +consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only +
    Returns:
    • If QuantityKindSpec<Q> is true, +returns remove-kind(q).
    • Otherwise, if +is-derived-from-specialization-of<Q, quantity_spec>() +is true, and +the specialization of Q​::​quantity_spec has a template argument equal to is_kind, +returns q.
    • Otherwise, if Q​::​parent is a valid expression, +returns get-kind-tree-root(Q​::​parent).
    • Otherwise, if DerivedQuantitySpec<Q> is true, +returns +expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) + +where to-kind is defined as follows: +template<QuantitySpec Q> +using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only +
    • Otherwise, returns q.
    template<QuantitySpec Q> +consteval QuantityKindSpec auto get_kind(Q); +
    Returns: kind_of<get-kind-tree-root(Q{})>.

    5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

    consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) + requires see below; +
    Let +
    • q1 be qs...[0],
    • q2 be qs...[1],
    • Q1 be decltype(q1),
    • Q2 be decltype(q2), and
    • rest be a pack denoting the elements of qs without q1 and q2.
    Effects: Equivalent to: +if constexpr (sizeof...(qs) == 1) + return q1; +else if constexpr (sizeof...(qs) == 2) { + using QQ1 = decltype(remove-kind(q1)); + using QQ2 = decltype(remove-kind(q2)); + + if constexpr (std::is_same_v<Q1, Q2>) + return q1; + else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) + return QQ1{}; + else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) + return QQ2{}; + else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || + (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && + implicitly_convertible(Q1{}, Q2{}))) + return q2; + else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || + (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && + implicitly_convertible(Q2{}, Q1{}))) + return q1; + else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) + return *common_base; + else if constexpr (implicitly_convertible(Q1{}, Q2{})) + return q2; + else if constexpr (implicitly_convertible(Q2{}, Q1{})) + return q1; + else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), + get-kind-tree-root(Q2{}))) + return get-kind-tree-root(q2); + else + return get-kind-tree-root(q1); +} else + return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(qs) != 0 && + (sizeof...(qs) == 1 || + (sizeof...(qs) == 2 && + (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || + QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || + requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); })) +

    5.4.3.6.4 Get common base [qty.get.common.base]

    In this subclause and [qty.is.child.of], +let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple +, +where par is parent.
    template<QuantitySpec auto A, QuantitySpec auto B> +consteval auto get-common-base(); // exposition only +
    Let +
    • be the number of elements in h(A),
    • be the number of elements in h(B),
    • s be ,
    • A be a tuple of the last s elements of h(A), and
    • B be a tuple of the last s elements of h(B).
    Effects: Looks for x, the first pair-wise equal element in A and B.
    Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.

    5.4.3.6.5 Is child of [qty.is.child.of]

    template<QuantitySpec Child, QuantitySpec Parent> +consteval bool is-child-of(Child ch, Parent p); // exposition only +
    Returns: If h(p) has more elements than h(ch), returns false.
    Otherwise, let C be a tuple of the last s elements of h(ch), +where s is the number of elements in h(p).
    Returns == p.

    5.4.4 Unit [qty.unit]

    5.4.4.1 General [qty.unit.general]

    Subclause [qty.unit] specifies the components +for defining a unit of measurement (IEC 60050, 112-01-14).

    5.4.4.2 Magnitude [qty.unit.mag]

    5.4.4.2.1 General [qty.unit.mag.general]

    Subclause [qty.unit.mag] specifies the components +used to represent the numerical value (IEC 60050, 112-01-29) of a unit +with support for powers (IEC 60050, 102-02-08) of real numbers (IEC 60050, 102-02-05).

    5.4.4.2.2 Concepts [qty.unit.mag.concepts]

    template<typename T> +concept MagConstant = SymbolicConstant<T> && is-derived-from-specialization-of<T, mag_constant>(); + +template<typename T> +concept UnitMagnitude = (is-specialization-of<T, unit-magnitude>()); + +template<typename T> +concept MagArg = std::integral<T> || MagConstant<T>; // exposition only +

    5.4.4.2.3 Types [qty.unit.mag.types]

    namespace mp_units { + +template<symbol_text Symbol, long double Value> + requires(Value > 0) +struct mag_constant { + static constexpr auto symbol = Symbol; // exposition only + static constexpr long double value = Value; // exposition only +}; + +} +
    A specialization of mag_constant represents a real number (IEC 60050, 102-02-05).
    Symbol is its symbol, and +Value is (an approximation of) its value.
    namespace mp_units { + +template<auto... Ms> +struct unit-magnitude { // exposition only + // [qty.unit.mag.ops], operations + + template<UnitMagnitude M> + friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); + + friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); + + template<UnitMagnitude Rhs> + friend consteval bool operator==(unit-magnitude, Rhs); + + template<int Num, int Den = 1> + friend consteval auto pow(unit-magnitude); // exposition only + + // [qty.unit.mag.utils], utilities + + friend consteval bool is-positive-integral-power(unit-magnitude); // exposition only + + template<auto... Ms2> + friend consteval auto common-magnitude(unit-magnitude, // exposition only + unit-magnitude<Ms2...>); +}; + +} +
    A specialization of unit-magnitude +represents the product of its template arguments.
    For the purposes of specifying the implementation-defined limits, +let the representation of the terms of unit-magnitude be the structure +struct { + ratio exp; + base-type base; +}; + +representing the number , +where base-type is a model of MagArg.
    • There is a single term for each base-type.
    • exp.num is not expanded into base.
      [Note 1: 
      is not permitted.
      — end note]
    • exp.den can reduce the base.
      [Note 2: 
      is permitted.
      — end note]
    • If the result of an operation on std​::​intmax_t values is undefined, +the behavior is +implementation-defined.

    5.4.4.2.4 Operations [qty.unit.mag.ops]

    template<UnitMagnitude M> +friend consteval UnitMagnitude auto operator*(unit-magnitude lhs, M rhs); +
    Returns:
    • If sizeof...(Ms) == 0 is true, returns rhs.
    • Otherwise, if std​::​is_same_v<M, unit-magnitude<>>, returns lhs.
    • Otherwise, returns an unspecified value equal to lhs ×rhs.
    friend consteval auto operator/(unit-magnitude lhs, UnitMagnitude auto rhs); +
    Returns: lhs * pow<-1>(rhs).
    template<UnitMagnitude Rhs> +friend consteval bool operator==(unit-magnitude, Rhs); +
    Returns: std​::​is_same_v<unit-magnitude, Rhs>.
    template<int Num, int Den = 1> +friend consteval auto pow(unit-magnitude base); // exposition only +
    Returns:
    • If Num == 0 is true, returns unit-magnitude<>{}.
    • Otherwise, returns an unspecified value equal to .
    template<MagArg auto V> +constexpr UnitMagnitude auto mag = see below; +
    Constraints: V is greater than 0.
    Effects: If MagConstant<decltype(V)> is satisfied, +initializes mag with unit-magnitude<V>{}.
    Otherwise, initializes mag with +an unspecified value equal to V.
    template<std::intmax_t N, std::intmax_t D> + requires(N > 0) +constexpr UnitMagnitude auto mag_ratio = see below; +
    Effects: Initializes mag_ratio with +an unspecified value equal to .
    template<MagArg auto Base, int Num, int Den = 1> +constexpr UnitMagnitude auto mag_power = pow<Num, Den>(mag<Base>); +
    Constraints: Base is greater than 0.

    5.4.4.2.5 Utilities [qty.unit.mag.utils]

    friend consteval bool is-positive-integral-power(unit-magnitude x); // exposition only +
    Returns: false if x has a negative or rational exponent, and +true otherwise.
    template<auto... Ms2> +friend consteval auto common-magnitude(unit-magnitude, unit-magnitude<Ms2...>); // exposition only +
    Returns: The largest magnitude C +such that each input magnitude is expressible +by only positive powers relative to C.

    5.4.4.3 Traits [qty.unit.traits]

    template<Unit auto U> +constexpr bool space_before_unit_symbol = true; +
    The formatting functions ([qty.unit.sym.fmt]) use space_before_unit_symbol +to determine whether there is a space +between the numerical value and the unit symbol.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize space_before_unit_symbol +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.4.4.4 Concepts [qty.unit.concepts]

    template<typename T> +concept Unit = SymbolicConstant<T> && std::derived_from<T, unit-interface>; + +template<typename T> +concept PrefixableUnit = Unit<T> && is-derived-from-specialization-of<T, named_unit>(); + +template<typename T> +concept AssociatedUnit = Unit<U> && has-associated-quantity(U{}); + +template<typename U, auto QS> +concept UnitOf = AssociatedUnit<U> && QuantitySpec<decltype(QS)> && + QuantitySpecConvertibleTo<get_quantity_spec(U{}), QS> && + (get_kind(QS) == get_kind(get_quantity_spec(U{})) || + !NestedQuantityKindSpecOf<get_quantity_spec(U{}), QS>); + +template<auto From, auto To> +concept UnitConvertibleTo = // exposition only + Unit<decltype(From)> && Unit<decltype(To)> && (convertible(From, To)); + +template<typename U, auto FromU, auto QS> +concept UnitCompatibleWith = // exposition only + Unit<U> && Unit<decltype(FromU)> && QuantitySpec<decltype(QS)> && + (!AssociatedUnit<U> || UnitOf<U, QS>) && UnitConvertibleTo<FromU, U{}>; + +template<typename T> +concept OffsetUnit = Unit<T> && requires { T::point-origin; }; // exposition only + +template<typename From, typename To> +concept PotentiallyConvertibleTo = // exposition only + Unit<From> && Unit<To> && + ((AssociatedUnit<From> && AssociatedUnit<To> && + implicitly_convertible(get_quantity_spec(From{}), get_quantity_spec(To{}))) || + (!AssociatedUnit<From> && !AssociatedUnit<To>)); +

    5.4.4.5 Types [qty.unit.types]

    5.4.4.5.1 Canonical [qty.canon.unit]

    namespace mp_units { + +template<UnitMagnitude M, Unit U> +struct canonical-unit { // exposition only + M mag; + U reference_unit; +}; + +} +
    canonical-unit represents a unit expressed in terms of base units (IEC 60050, 112-01-18).
    [Note 1: 
    Other types representing units are equal only if they have the same type.
    canonical-unit is used to implement binary relations other than equality.
    — end note]
    reference_unit is simplified ([qty.sym.expr.algos]).
    consteval auto get-canonical-unit(Unit auto u); // exposition only +
    Returns: The instantiation of canonical-unit for u.

    5.4.4.5.2 Scaled [qty.scaled.unit]

    namespace mp_units { + +template<UnitMagnitude auto M, Unit U> + requires(M != unit-magnitude<>{} && M != mag<1>) +struct scaled_unit final : unit-interface { + using base-type = scaled_unit; // exposition only + static constexpr UnitMagnitude auto mag = M; // exposition only + static constexpr U reference-unit{}; // exposition only + static constexpr auto point-origin = U::point_origin; // exposition only, present only + // if the qualified-id U​::​point_origin is valid and denotes an object +}; + +} +
    scaled_unit<M, U> is used by the library +to represent the unit M ×U.

    5.4.4.5.3 Named [qty.named.unit]

    namespace mp_units { + +template<symbol_text Symbol, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, QuantityKindSpec auto QS, PointOrigin auto PO> + requires(!Symbol.empty()) && BaseDimension<decltype(auto(QS.dimension))> +struct named_unit<Symbol, QS, PO> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol> + requires(!Symbol.empty()) +struct named_unit<Symbol> : unit-interface { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U> + requires(!Symbol.empty()) +struct named_unit<Symbol, U> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only +}; + +template<symbol_text Symbol, Unit auto U, PointOrigin auto PO> + requires(!Symbol.empty()) +struct named_unit<Symbol, U, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only +}; + +template<symbol_text Symbol, AssociatedUnit auto U, QuantityKindSpec auto QS, + PointOrigin auto PO> + requires(!Symbol.empty()) && (QS.dimension == get-associated-quantity(U).dimension) +struct named_unit<Symbol, U, QS, PO> : decltype(U)::base-type { + using base-type = named_unit; // exposition only + static constexpr auto symbol = Symbol; // exposition only + static constexpr auto quantity-spec = QS; // exposition only + static constexpr auto point-origin = PO; // exposition only +}; + +} +
    A named unit is a type that models PrefixableUnit.
    A specialization of named_unit is used as a base type when defining a named unit.
    In the following descriptions, let U be a named unit defined with an alluded signature.
    The identifier of U represents +its unit name (IEC 60050, 112-01-15) +or special unit name (IEC 60050, 112-01-16).
    Symbol is its unit symbol (IEC 60050, 112-01-17).
    The possible arguments to named_unit are +
    • ,
    • ,
    • , and
    • .
    The first signature defines the unit of a base quantity +without a unit prefix (IEC 60050, 112-01-26).
    The second signature defines a unit +that can be reused by several base quantities.
    The third and fourth signatures with a unit expression argument E +define U as implicitly convertible from E.
    The first and fourth signatures with a kind of quantity (IEC 60050, 112-01-04) Q +also restrict U to Q.
    A point origin argument specifies the default point origin of U ([qty.pt.syn]).
    [Example 1: // 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; // . + +// The fourth signature also further restricts the kind of quantity. +inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> { +} hertz; // Hz can't measure becquerel, activity, + // or any other quantity with dimension + // that isn't a kind of frequency. + — end example]

    5.4.4.5.4 Prefixed [qty.prefixed.unit]

    namespace mp_units { + +template<symbol_text Symbol, UnitMagnitude auto M, PrefixableUnit auto U> + requires(!Symbol.empty()) +struct prefixed_unit : decltype(M * U)::base-type { + using base-type = prefixed_unit; // exposition only + static constexpr auto symbol = Symbol + U.symbol; // exposition only +}; + +} +
    prefixed_unit<Symbol, M, U> represents the unit U with a unit prefix (IEC 60050, 112-01-26).
    Symbol is the symbol of the unit prefix.
    M is the factor of the unit prefix.
    A specialization of prefixed_unit is used as a base type when defining a unit prefix.
    [Example 1: template<PrefixableUnit auto U> +struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; + +template<PrefixableUnit auto U> +constexpr kilo_<U> kilo; + +inline constexpr auto kilogram = kilo<si::gram>; + — end example]

    5.4.4.5.5 Common [qty.common.unit]

    namespace mp_units { + +template<Unit U1, Unit U2, Unit... Rest> +struct common_unit final : decltype(get-common-scaled-unit(U1{}, U2{}, Rest{}...))::base-type +{ + using base-type = common_unit; // exposition only + static constexpr auto common-unit = // exposition only + get-common-scaled-unit(U1{}, U2{}, Rest{}...); +}; + +} +
    common_unit is used by the library +to encapsulate a conversion factor between units (IEC 60050, 112-01-33) +common to the operands of quantity addition.
    [Example 1: 
    The result of 1 * km + 1 * mi +has a common unit +encapsulated by common_unit<mi, km>.
    — end example]
    +A program that instantiates a specialization of common_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.
    template<Unit U1, Unit U2, Unit... Rest> +consteval Unit auto get-common-scaled-unit(U1, U2, Rest... rest) // exposition only + requires see below; +
    Effects: Equivalent to: +constexpr auto res = [] { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + constexpr auto common_mag = common-magnitude(canonical_lhs.mag, canonical_rhs.mag); + if constexpr (common_mag == mag<1>) + return canonical_lhs.reference_unit; + else + return scaled_unit<common_mag, decltype(auto(canonical_lhs.reference_unit))>{}; +}(); +if constexpr (sizeof...(rest) == 0) + return res; +else + return get-common-scaled-unit(res, rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(U1{}, U2{}) && (sizeof...(Rest) == 0 || requires { + get-common-scaled-unit(get-common-scaled-unit(u1, u2), rest...); + })) +

    5.4.4.5.6 Derived [qty.derived.unit]

    namespace mp_units { + +template<typename... Expr> +struct derived-unit-impl : // exposition only + unit-interface, + expr-fractions<struct one, Expr...> { + using base-type = derived-unit-impl; // exposition only +}; + +template<SymbolicConstant... Expr> +struct derived_unit final : derived-unit-impl<Expr...> {}; + +} +
    derived_unit is used by the library +to represent a derived unit (IEC 60050, 112-01-19).
    [Example 1: using namespace si::unit_symbols; +int x = m * m; // error: cannot construct from derived_unit<power<si​::​metre, 2>> +int y = m * s; // error: cannot construct from derived_unit<si​::​metre, si​::​second> +int z = m / s; // error: cannot construct from derived_unit<si​::​metre, per<si​::​second>> + — end example]
    +A program that instantiates a specialization of derived_unit +that is not a possible result of the library specifications +is ill-formed, no diagnostic required.

    5.4.4.5.7 One [qty.unit.one]

    namespace mp_units { + +struct one final : derived-unit-impl<> {}; + +} +
    one represents the base unit (IEC 60050, 112-01-18) of a quantity of dimension one (IEC 60050, 112-01-13).

    5.4.4.6 Operations [qty.unit.ops]

    namespace mp_units { + +struct unit-interface { // exposition only + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator*(M, U u); + + friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; + + template<UnitMagnitude M, Unit U> + friend consteval Unit auto operator/(M mag, U u); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); + + // [qty.unit.cmp], comparison + + template<Unit Lhs, Unit Rhs> + friend consteval bool operator==(Lhs, Rhs); + + template<Unit Lhs, Unit Rhs> + friend consteval bool equivalent(Lhs lhs, Rhs rhs); +}; + +} +
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator*(M, U u); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<M, decltype(auto(mag<1>))>) + return u; +else if constexpr (is-specialization-of<U, scaled_unit>()) { + if constexpr (M{} * U::mag == mag<1>) + return U::reference-unit; + else + return scaled_unit<M{} * U::mag, decltype(auto(U::reference-unit))>{}; +} else + return scaled_unit<M{}, U>{}; +
    friend consteval Unit auto operator*(Unit auto, UnitMagnitude auto) = delete; +
    Recommended practice: Suggest swapping the operands.
    template<UnitMagnitude M, Unit U> +friend consteval Unit auto operator/(M mag, U u); +
    Returns: mag * inverse(u).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator*(Lhs lhs, Rhs rhs); +
    Returns: expr-multiply<derived_unit, struct one>(lhs, rhs).
    template<Unit Lhs, Unit Rhs> +friend consteval Unit auto operator/(Lhs lhs, Rhs rhs); +
    Returns: expr-divide<derived_unit, struct one>(lhs, rhs).
    consteval Unit auto inverse(Unit auto u); +
    Returns: one / u.
    template<std::intmax_t Num, std::intmax_t Den = 1, Unit U> + requires(Den != 0) +consteval Unit auto pow(U u); +
    Returns: expr-pow<Num, Den, derived_unit, struct one>(u).
    consteval Unit auto sqrt(Unit auto u); +
    Returns: pow<1, 2>(u).
    consteval Unit auto cbrt(Unit auto u); +
    Returns: pow<1, 3>(u).
    consteval Unit auto square(Unit auto u); +
    Returns: pow<2>(u).
    consteval Unit auto cubic(Unit auto u); +
    Returns: pow<3>(u).

    5.4.4.7 Comparison [qty.unit.cmp]

    template<Unit Lhs, Unit Rhs> +friend consteval bool operator==(Lhs, Rhs); +
    Returns: std​::​is_same_v<Lhs, Rhs>.
    template<Unit Lhs, Unit Rhs> +friend consteval bool equivalent(Lhs lhs, Rhs rhs); +
    Effects: Equivalent to: +const auto lhs_canonical = get-canonical-unit(lhs); +const auto rhs_canonical = get-canonical-unit(rhs); +return lhs_canonical.mag == rhs_canonical.mag && + lhs_canonical.reference_unit == rhs_canonical.reference_unit; +
    template<Unit From, Unit To> +consteval bool convertible(From from, To to); +
    Effects: Equivalent to: +if constexpr (std::is_same_v<From, To>) + return true; +else if constexpr (PotentiallyConvertibleTo<From, To>) + return std::is_same_v<decltype(get-canonical-unit(from).reference_unit), + decltype(get-canonical-unit(to).reference_unit)>; +else + return false; +

    5.4.4.8 Observers [qty.unit.obs]

    consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u); +
    Returns: kind_of<get-associated-quantity(u)>.
    consteval Unit auto get_unit(AssociatedUnit auto u); +
    Returns: u.
    consteval Unit auto get_common_unit(Unit auto... us) + requires see below; +
    Let +
    • u1 be us...[0],
    • u2 be us...[1],
    • U1 be decltype(u1),
    • U2 be decltype(u2), and
    • rest be a pack denoting the elements of us without u1 and u2.
    Effects: Equivalent to: +if constexpr (sizeof...(us) == 1) + return u1; +else if constexpr (sizeof...(us) == 2) { + if constexpr (is-derived-from-specialization-of<U1, common_unit>()) { + return TBD.; + } else if constexpr (is-derived-from-specialization-of<U2, common_unit>()) + return get_common_unit(u2, u1); + else if constexpr (std::is_same_v<U1, U2>) + return u1; + else if constexpr (equivalent(U1{}, U2{})) { + if constexpr (std::derived_from<U1, typename U2::base-type>) + return u1; + else if constexpr (std::derived_from<U2, typename U1::base-type>) + return u2; + else + return std::conditional_t<type-less-impl<U1, U2>(), U1, U2>{}; + } else { + constexpr auto canonical_lhs = get-canonical-unit(U1{}); + constexpr auto canonical_rhs = get-canonical-unit(U2{}); + + if constexpr (is-positive-integral-power(canonical_lhs.mag / canonical_rhs.mag)) + return u2; + else if constexpr (is-positive-integral-power(canonical_rhs.mag / canonical_lhs.mag)) + return u1; + else { + if constexpr (type-less<U1, U2>{}) + return common_unit<U1, U2>{}; + else + return common_unit<U2, U1>{}; + } + } +} else + return get_common_unit(get_common_unit(u1, u2), rest...); +
    Remarks: The expression in the requires-clause is equivalent to: +(sizeof...(us) != 0 && (sizeof...(us) == 1 || // + (sizeof...(us) == 2 && convertible(U1{}, U2{})) || + requires { get_common_unit(get_common_unit(u1, u2), rest...); })) +

    5.4.4.9 Associated quantity [assoc.qty]

    template<Unit U> +consteval bool has-associated-quantity(U); // exposition only +
    Returns:
    • If U​::​quantity-spec is a valid expression, +returns true.
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +has-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +let Nums and Dens +be packs denoting the template arguments of +U​::​nums and U​::​dens, respectively.
      Returns +(... && has-associated-quantity(expr-type<Nums>{})) && + (... && has-associated-quantity(expr-type<Dens>{})) +
    • Otherwise, returns false.
    template<AssociatedUnit U> +consteval auto get-associated-quantity(U u); // exposition only +
    Returns:
    • If U is of the form common_unit<Us...>, +returns +get_common_quantity_spec(get-associated-quantity(Us{})...) +
    • Otherwise, if U​::​quantity-spec is a valid expression, +returns +remove-kind(U::quantity-spec) +
    • Otherwise, if U​::​reference-unit is a valid expression, +returns +get-associated-quantity(U::reference-unit) +
    • Otherwise, if +is-derived-from-specialization-of<U, expr-fractions>() +is true, +returns +expr-map<to-quantity-spec, derived_quantity_spec, struct dimensionless>(u) + +where to-quantity-spec is defined as follows: +template<AssociatedUnit U> +using to-quantity-spec = decltype(get-associated-quantity(U{})); // exposition only +

    5.4.4.10 Symbol formatting [qty.unit.sym.fmt]

    template<typename CharT = char, std::output_iterator<CharT> Out, Unit U> +constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = {}); +
    Effects: TBD.
    Returns: TBD.
    template<unit_symbol_formatting fmt = {}, typename CharT = char, Unit U> +consteval std::string_view unit_symbol(U); +
    Effects: Equivalent to: +TBD. +

    5.4.5 Concepts [qty.ref.concepts]

    template<typename T> +concept Reference = AssociatedUnit<T> || (is-specialization-of<T, reference>()); +
    A type T that satisfies Reference +represents the reference of a quantity (IEC 60050, 112-01-01).
    template<typename T, auto QS> +concept ReferenceOf = Reference<T> && QuantitySpecOf<decltype(get_quantity_spec(T{})), QS>; +

    5.4.6 Class template reference [qty.ref.syn]

    namespace mp_units { + +template<QuantitySpec auto Q, Unit auto U> +using reference-t = reference<decltype(Q), decltype(U)>; // exposition only + +template<QuantitySpec Q, Unit U> +struct reference { + // [qty.ref.ops], operations + + template<typename Q2, typename U2> + friend consteval auto operator*(reference, reference<Q2, U2>) + -> reference-t<Q{} * Q2{}, U{} * U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator*(reference, U2) + -> reference-t<Q{} * get_quantity_spec(U2{}), U{} * U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator*(U1, reference) + -> reference-t<get_quantity_spec(U1{}) * Q{}, U1{} * U{}>; + + template<typename Q2, typename U2> + friend consteval auto operator/(reference, reference<Q2, U2>) + -> reference-t<Q{} / Q2{}, U{} / U2{}>; + + template<AssociatedUnit U2> + friend consteval auto operator/(reference, U2) + -> reference-t<Q{} / get_quantity_spec(U2{}), U{} / U2{}>; + + template<AssociatedUnit U1> + friend consteval auto operator/(U1, reference) + -> reference-t<get_quantity_spec(U1{}) / Q{}, U1{} / U{}>; + + friend consteval auto inverse(reference) -> reference-t<inverse(Q{}), inverse(U{})>; + + template<std::intmax_t Num, std::intmax_t Den = 1> + requires(Den != 0) + friend consteval auto pow(reference) -> reference-t<pow<Num, Den>(Q{}), pow<Num, Den>(U{})>; + friend consteval auto sqrt(reference) -> reference-t<sqrt(Q{}), sqrt(U{})>; + friend consteval auto cbrt(reference) -> reference-t<cbrt(Q{}), cbrt(U{})>; + + // [qty.ref.cmp], comparison + + template<typename Q2, typename U2> + friend consteval bool operator==(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool operator==(reference, U2 u2); + + template<typename Q2, typename U2> + friend consteval bool convertible(reference, reference<Q2, U2>); + + template<AssociatedUnit U2> + friend consteval bool convertible(reference, U2 u2); + + template<AssociatedUnit U1> + friend consteval bool convertible(U1 u1, reference); +}; + +} +
    reference<Q, U> represents the reference of a quantity (IEC 60050, 112-01-01).
    The unit of measurement U (IEC 60050, 112-01-14) +is used to measure a value of the quantity Q (IEC 60050, 112-01-28).
    [Note 1: 
    reference is typically implicitly instantiated +when specifying that a unit measures a more specific quantity.
    [Example 1: using namespace si::unit_symbols; +auto x = 1 * m; // measures a length +auto y = 1 * isq::width[m]; // measures a width +auto z = 1 * isq::diameter[m]; // measures a diameter + — end example]
    — end note]

    5.4.7 Operations [qty.ref.ops]

    Each member function with a trailing-return-type +of -> reference-t<T...> +returns {}.
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R r); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), r};
    template<typename FwdRep, Reference R, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + requires(!OffsetUnit<decltype(get_unit(R{}))>) +constexpr Quantity auto operator/(FwdRep&& lhs, R); +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), inverse(R{})};
    template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator*(FwdQ&& q, R); +template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>> +constexpr Quantity auto operator/(FwdQ&& q, R); +
    Let @ be the operator.
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, Q::reference @ R{}}; +
    template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator*(R, Rep&&) = delete; + +template<Reference R, typename Rep> + requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{})> +constexpr auto operator/(R, Rep&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator*(R, Q&&) = delete; + +template<Reference R, typename Q> + requires Quantity<std::remove_cvref_t<Q>> +constexpr auto operator/(R, Q&&) = delete; +
    Recommended practice: Suggest swapping the operands.

    5.4.8 Comparison [qty.ref.cmp]

    template<typename Q2, typename U2> +friend consteval bool operator==(reference, reference<Q2, U2>); +
    Returns: Q{} == Q2{} && U{} == U2{}.
    template<AssociatedUnit U2> +friend consteval bool operator==(reference, U2 u2); +
    Returns: Q{} == get_quantity_spec(u2) && U{} == u2.
    template<typename Q2, typename U2> +friend consteval bool convertible(reference, reference<Q2, U2>); +
    Returns: implicitly_convertible(Q{}, Q2{}) && convertible(U{}, U2{}).
    template<AssociatedUnit U2> +friend consteval bool convertible(reference, U2 u2); +
    Returns: implicitly_convertible(Q{}, get_quantity_spec(u2)) && convertible(U{}, u2).
    template<AssociatedUnit U1> +friend consteval bool convertible(U1 u1, reference); +
    Returns: implicitly_convertible(get_quantity_spec(u1), Q{}) && convertible(u1, U{}).

    5.4.9 Observers [qty.ref.obs]

    template<typename Q, typename U> +consteval QuantitySpec auto get_quantity_spec(reference<Q, U>); +
    Returns: Q{}.
    template<typename Q, typename U> +consteval Unit auto get_unit(reference<Q, U>); +
    Returns: U{}.
    consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, + AssociatedUnit auto u2, + AssociatedUnit auto... rest) + requires see below; +
    Returns: get_common_unit(u1, u2, rest...).
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), + get_quantity_spec(rest)...); + { get_common_unit(u1, u2, rest...) } -> AssociatedUnit; +} +
    template<Reference R1, Reference R2, Reference... Rest> +consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest) + requires see below; +
    Returns: reference-t<get_common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}), + get_quantity_spec(rest)...), + get_common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + get_common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), + get_quantity_spec(rest)...); + get_common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...); +} +

    5.5 Representation [qty.rep]

    5.5.1 General [qty.rep.general]

    Subclause [qty.rep] specifies the components +used to constrain the numerical value of a quantity (IEC 60050, 112-01-29).

    5.5.2 Traits [qty.rep.traits]

    5.5.2.1 Floating-point [qty.fp.traits]

    template<typename T> +struct actual-value-type : cond-value-type<T> {}; // see N4971, [readable.traits] + +template<typename T> + requires(!std::is_pointer_v<T> && !std::is_array_v<T>) && + requires { typename std::indirectly_readable_traits<T>::value_type; } +struct actual-value-type<T> : std::indirectly_readable_traits<T> {}; + +template<typename T> +using actual-value-type-t = actual-value-type<T>::value_type; + +template<typename Rep> +constexpr bool treat_as_floating_point = + std::chrono::treat_as_floating_point_v<actual-value-type-t<Rep>>; +
    quantity and quantity_point use treat_as_floating_point +to help determine whether implicit conversions are allowed among them.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize treat_as_floating_point +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.

    5.5.2.2 Quantity character [qty.char.traits]

    template<typename T> +constexpr bool disable_scalar = false; +template<typename T> +constexpr bool disable_complex = false; +template<typename T> +constexpr bool disable_vector = false; +
    Some quantities are defined as having a numerical value (IEC 60050, 112-01-29) of a specific set (IEC 60050, 102-01-02).
    The representation concepts use these traits +to help determine the sets T represents.
    Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), +users may specialize these templates +for cv-unqualified program-defined types.
    Such specializations shall be usable in constant expressions (N4971, [expr.const]) +and have type const bool.
    [Note 1: 
    These templates prevent use of representation types with the library +that satisfy but do not in fact model their corresponding concept.
    — end note]

    5.5.2.3 Values [qty.val.traits]

    quantity and quantity_point use representation_values +to construct special values of its representation type.
    namespace mp_units { + +template<typename Rep> +struct representation_values : std::chrono::duration_values<Rep> { + static constexpr Rep one() noexcept; +}; + +} +
    The requirements on std​::​chrono​::​duration_values<Rep> (N4971, [time.traits.duration.values]) +also apply to representation_values<Rep>.
    static constexpr Rep one() noexcept; +
    Returns: Rep(1).
    Remarks: The value returned shall be the neutral element for multiplication (IEC 60050, 102-01-19).

    5.5.3 Customization point objects [qty.rep.cpos]

    5.5.3.2 mp_units​::​real [qty.real.cpo]

    The name mp_units​::​real denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​real(E) is ill-formed.
    • If auto(t.real()) is a valid expression whose type models Scalar, +mp_units​::​real(E) is expression-equivalent to auto(t.real()).
    • Otherwise, if T is a class or enumeration type and +auto(real(t)) is a valid expression whose type models Scalar +where the meaning of real is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​real(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​real(E) is ill-formed.

    5.5.3.3 mp_units​::​imag [qty.imag.cpo]

    The name mp_units​::​imag denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​imag(E) is ill-formed.
    • If auto(t.imag()) is a valid expression whose type models Scalar, +mp_units​::​imag(E) is expression-equivalent to auto(t.imag()).
    • Otherwise, if T is a class or enumeration type and +auto(imag(t)) is a valid expression whose type models Scalar +where the meaning of imag is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​imag(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​imag(E) is ill-formed.

    5.5.3.4 mp_units​::​modulus [qty.modulus.cpo]

    The name mp_units​::​modulus denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​modulus(E) is ill-formed.
    • If auto(t.modulus()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.modulus()).
    • Otherwise, if T is a class or enumeration type and +auto(modulus(t)) is a valid expression whose type models Scalar +where the meaning of modulus is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • If auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​modulus(E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of abs is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​modulus(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​modulus(E) is ill-formed.

    5.5.3.5 mp_units​::​magnitude [qty.mag.cpo]

    The name mp_units​::​magnitude denotes a customization point object (N4971, [customization.point.object]).
    Given a subexpression E with type T, +let t be an lvalue that denotes the reified object for E.
    Then: +
    • If T does not model WeaklyRegular, +mp_units​::​magnitude(E) is ill-formed.
    • If auto(t.magnitude()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(E) is expression-equivalent to auto(t.magnitude()).
    • Otherwise, if T is a class or enumeration type and +auto(magnitude(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, if auto(t.abs()) is a valid expression whose type models Scalar, +mp_units​::​magnitude(​E) is expression-equivalent to auto(t.abs()).
    • Otherwise, if T is a class or enumeration type and +auto(abs(t)) is a valid expression whose type models Scalar +where the meaning of magnitude is established as-if by performing argument-dependent lookup only (N4971, [basic.lookup.argdep]), +then mp_units​::​magnitude(E) is expression-equivalent to that expression.
    • Otherwise, mp_units​::​magnitude(E) is ill-formed.

    5.5.4 Concepts [qty.rep.concepts]

    template<typename T> +concept WeaklyRegular = std::copyable<T> && std::equality_comparable<T>; // exposition only + +template<typename T> +concept Scalar = (!disable_scalar<T>) && WeaklyRegular<T> && requires(T a, T b) { // exposition only + // 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>; +}; +
    TBD.
    template<typename T> +using value-type-t = actual-value-type-t<T>; // exposition only, see [qty.fp.traits] + +template<typename T> +concept Complex = // exposition only + (!disable_complex<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + std::constructible_from<T, value-type-t<T>, value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +concept Vector = // exposition only + (!disable_vector<T>) && WeaklyRegular<T> && Scalar<value-type-t<T>> && + requires(T a, T b, 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); + }; +
    TBD.
    template<typename T> +using scaling-factor-type-t = // exposition only + std::conditional_t<treat_as_floating_point<T>, long double, std::intmax_t>; + +template<typename T> +concept ScalarRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Scalar<T> && + requires(T a, T b, 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>; + }; +
    TBD.
    template<typename T> +concept ComplexRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Complex<T> && + requires(T a, T b, scaling-factor-type-t<T> f) { + // scaling + { a * T(f) } -> std::common_with<T>; + { T(f) * a } -> std::common_with<T>; + { a / T(f) } -> std::common_with<T>; + }; +
    TBD.
    template<typename T> +concept VectorRepresentation = // exposition only + (!is-specialization-of<T, quantity>()) && Vector<T>; +
    TBD.
    template<typename T> +concept Representation = ScalarRepresentation<T> || ComplexRepresentation<T> || + VectorRepresentation<T>; +
    A type T models Representation if +it represents the numerical value of a quantity (IEC 60050, 112-01-29).
    template<typename T, quantity_character Ch> +concept IsOfCharacter = (Ch == quantity_character::scalar && Scalar<T>) || // exposition only + (Ch == quantity_character::complex && Complex<T>) || + (Ch == quantity_character::vector && Vector<T>); + +template<typename T, auto V> +concept RepresentationOf = + Representation<T> && ((QuantitySpec<decltype(V)> && + (QuantityKindSpec<decltype(V)> || IsOfCharacter<T, V.character>)) || + (std::same_as<quantity_character, decltype(V)> && IsOfCharacter<T, V>)); +
    A type T models RepresentationOf<V> if +T models Representation and +
    • V is a kind of quantity, or
    • if V is a quantity, then T represents a value of its character, or
    • if V is a quantity character, then T represents a value of V.

    5.6 Quantity [qty]

    5.6.1 General [qty.general]

    Subclause [qty] describes the class template quantity +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of a vector space (IEC 60050, 102-03-01,102-03-04).

    5.6.2 Interoperability [qty.like]

    The interfaces specified in this subclause and subclause [qty.pt.like] +are used by quantity and quantity_point +to specify conversions with other types representing quantities.
    [Note 1: 
    [qty.chrono] implements them for std​::​chrono​::​duration and std​::​chrono​::​time_point.
    — end note]
    template<typename T, template<typename> typename Traits> +concept qty-like-impl = requires(const T& qty, const Traits<T>::rep& num) { // exposition only + { Traits<T>::to_numerical_value(qty) } -> std::same_as<typename Traits<T>::rep>; + { Traits<T>::from_numerical_value(num) } -> std::same_as<T>; + requires std::same_as<decltype(Traits<T>::explicit_import), const bool>; + requires std::same_as<decltype(Traits<T>::explicit_export), const bool>; + typename std::bool_constant<Traits<T>::explicit_import>; + typename std::bool_constant<Traits<T>::explicit_export>; +}; + +template<typename T> +concept QuantityLike = !Quantity<T> && qty-like-impl<T, quantity_like_traits> && requires { + typename quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; +}; +
    In the following descriptions, let +
    • Traits be quantity_like_traits or quantity_point_like_traits,
    • Q be a type for which Traits<Q> is specialized,
    • qty be an lvalue of type const Q, and
    • num be an lvalue of type const Traits<Q>​::​rep.
    Q models qty-like-impl<Traits> if and only if: +
    • Traits<Q>​::​to_numerical_value(qty) returns the numerical value (IEC 60050, 112-01-29) of qty.
    • Traits<Q>​::​from_numerical_value(num) returns a Q with numerical value num.
    • If Traits is quantity_point_like_traits, +both numerical values are offset from Traits<Q>​::​point_origin.
    If the following expression is true, the specified conversion will be explicit.
    • Traits<Q>​::​explicit_import for the conversion from Q to this library's type.
    • Traits<Q>​::​explicit_export for the conversion from this library's type to Q.

    5.6.3 Class template quantity [qty.syn]

    namespace mp_units { + +template<typename T> +concept Quantity = (is-derived-from-specialization-of<T, quantity>()); // exposition only + +template<typename Q, auto QS> +concept QuantityOf = // exposition only + Quantity<Q> && QuantitySpecOf<decltype(auto(Q::quantity_spec)), QS>; + +template<Unit UFrom, Unit UTo> +consteval bool integral-conversion-factor(UFrom from, UTo to) // exposition only +{ + return is-integral(get-canonical-unit(from).mag / get-canonical-unit(to).mag); +} + +template<typename T> +concept IsFloatingPoint = treat_as_floating_point<T>; // exposition only + +template<typename FromRep, typename ToRep, auto FromUnit = one, auto ToUnit = one> +concept ValuePreservingTo = // exposition only + Representation<std::remove_cvref_t<FromRep>> && Representation<ToRep> && + Unit<decltype(FromUnit)> && Unit<decltype(ToUnit)> && std::assignable_from<ToRep&, FromRep> && + (IsFloatingPoint<ToRep> || (!IsFloatingPoint<std::remove_cvref_t<FromRep>> && + (integral-conversion-factor(FromUnit, ToUnit)))); + +template<typename QFrom, typename QTo> +concept QuantityConvertibleTo = // exposition only + Quantity<QFrom> && Quantity<QTo> && + QuantitySpecConvertibleTo<QFrom::quantity_spec, QTo::quantity_spec> && + UnitConvertibleTo<QFrom::unit, QTo::unit> && + ValuePreservingTo<typename QFrom::rep, typename QTo::rep, QFrom::unit, QTo::unit> && + requires(QFrom q) { sudo-cast<QTo>(q); }; // see [qty.non.mem.conv] + +template<auto QS, typename Func, typename T, typename U> +concept InvokeResultOf = // exposition only + QuantitySpec<decltype(QS)> && std::regular_invocable<Func, T, U> && + RepresentationOf<std::invoke_result_t<Func, T, U>, QS>; + +template<typename Func, typename Q1, typename Q2, + auto QS = std::invoke_result_t<Func, decltype(auto(Q1::quantity_spec)), + decltype(auto(Q2::quantity_spec))>{}> +concept InvocableQuantities = // exposition only + QuantitySpec<decltype(QS)> && Quantity<Q1> && Quantity<Q2> && + InvokeResultOf<QS, Func, typename Q1::rep, typename Q2::rep>; + +template<auto R1, auto R2> +concept HaveCommonReference = requires { get_common_reference(R1, R2); }; // exposition only + +template<typename Func, Quantity Q1, Quantity Q2> +using common-quantity-for = // exposition only + quantity<get_common_reference(Q1::reference, Q2::reference), + std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>; + +template<typename Func, typename Q1, typename Q2> +concept CommonlyInvocableQuantities = // exposition only + Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> && + std::convertible_to<Q1, common-quantity-for<Func, Q1, Q2>> && + std::convertible_to<Q2, common-quantity-for<Func, Q1, Q2>> && + InvocableQuantities<Func, Q1, Q2, + get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>; + +template<auto R1, auto R2, typename Rep1, typename Rep2> +concept SameValueAs = // exposition only + (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>; + +template<typename T> +using quantity-like-type = // exposition only + quantity<quantity_like_traits<T>::reference, typename quantity_like_traits<T>::rep>; + +template<typename T, typename U, typename TT = std::remove_reference_t<T>> +concept Mutable = (!std::is_const_v<TT>) && std::derived_from<TT, U>; // exposition only + +template<Reference auto R, RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity { +public: + Rep numerical-value; // exposition only + + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + using rep = Rep; + + // [qty.static], static member functions + static constexpr quantity zero() noexcept + requires see below; + static constexpr quantity one() noexcept + requires see below; + static constexpr quantity min() noexcept + requires see below; + static constexpr quantity max() noexcept + requires see below; + + // [qty.cons], constructors and assignment + + quantity() = default; + quantity(const quantity&) = default; + quantity(quantity&&) = default; + ~quantity() = default; + + template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> + constexpr quantity(FwdValue&& v, R2); + + template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> + constexpr quantity(FwdValue&& v, R2); + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity(FwdValue&& v); + + template<QuantityConvertibleTo<quantity> Q> + constexpr explicit(see below) quantity(const Q& q); + + template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> + constexpr explicit(see below) quantity(const Q& q); + + quantity& operator=(const quantity&) = default; + quantity& operator=(quantity&&) = default; + + template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) + constexpr quantity& operator=(FwdValue&& v); + + // [qty.conv], conversions + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> + constexpr QuantityOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> + constexpr QuantityOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } + constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; + + // [qty.obs], numerical value observers + + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr rep& numerical_value_ref_in(U) & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + constexpr const rep& numerical_value_ref_in(U) const & noexcept; + template<Unit U> + requires(equivalent(U{}, unit)) + void numerical_value_ref_in(U) const && = delete; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> + constexpr rep numerical_value_in(U) const noexcept; + + template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } + constexpr rep force_numerical_value_in(U) const noexcept; + + // [qty.conv.ops], conversion operations + + template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) + explicit operator V_() const & noexcept; + + template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> + constexpr explicit(see below) operator Q_() const noexcept(see below); + + // [qty.unary.ops], unary operations + + constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; + constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; + + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator++(Q&& q) + requires see below; + template<Mutable<quantity> Q> + friend constexpr decltype(auto) operator--(Q&& q) + requires see below; + + constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; + constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; + + // [qty.assign.ops], compound assignment operations + + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); + template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); + + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); + template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); + + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); + template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below + friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); + + // [qty.arith.ops], arithmetic operations + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> + friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> + friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> + friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> + friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> + friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); + + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> + friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); + template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> + friend constexpr Quantity auto operator/(const Value&, const Q&); + + // [qty.cmp], comparison + + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); + template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); + + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr bool operator==(const Q& lhs, const Value& rhs); + template<std::derived_from<quantity> Q, Representation Value> + requires see below + friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); + + // [qty.val.cmp], value comparison + friend constexpr bool is_eq_zero(const quantity& q) requires see below; + friend constexpr bool is_neq_zero(const quantity& q) requires see below; + friend constexpr bool is_lt_zero(const quantity& q) requires see below; + friend constexpr bool is_gt_zero(const quantity& q) requires see below; + friend constexpr bool is_lteq_zero(const quantity& q) requires see below; + friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +}; + +template<Representation Value, Reference R> +quantity(Value, R) -> quantity<R{}, Value>; + +template<Representation Value> +quantity(Value) -> quantity<one, Value>; + +template<QuantityLike Q> +explicit(quantity_like_traits<Q>::explicit_import) quantity(Q) + -> quantity<quantity_like_traits<Q>::reference, typename quantity_like_traits<Q>::rep>; + +} +
    quantity<R, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.

    5.6.4 Static member functions [qty.static]

    static constexpr quantity zero() noexcept + requires see below; +static constexpr quantity one() noexcept + requires see below; +static constexpr quantity min() noexcept + requires see below; +static constexpr quantity max() noexcept + requires see below; +
    Let F be one of zero, one, min, and max.
    Returns: {representation_values<rep>​::​F(), R}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { representation_values<rep>::F(); } +

    5.6.5 Constructors and assignment [qty.cons]

    template<typename FwdValue, Reference R2> + requires SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep> +constexpr quantity(FwdValue&& v, R2); + +template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity(FwdValue&& v); +
    Effects: Initializes numerical-value with std​::​forward<FwdValue>(v).
    template<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>> + requires(!SameValueAs<R2{}, R, Value, Rep>) && + QuantityConvertibleTo<quantity<R2{}, Value>, quantity> +constexpr quantity(FwdValue&& v, R2); +
    Effects: Equivalent to +quantity(quantity<R2{}, Value>{std​::​forward<FwdValue>(v), R2{}}).
    template<QuantityConvertibleTo<quantity> Q> +constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q); +
    Effects: Equivalent to sudo-cast<quantity>(q) ([qty.non.mem.conv]).
    template<QuantityLike Q> + requires QuantityConvertibleTo<quantity-like-type<Q>, quantity> +constexpr explicit(see below) quantity(const Q& q); +
    Effects: Equivalent to: +quantity(::mp_units::quantity{quantity_like_traits<Q>::to_numerical_value(q), + quantity_like_traits<Q>::reference}) +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_import || + !std::convertible_to<typename quantity_like_traits<Q>::rep, Rep> +
    template<ValuePreservingTo<Rep> FwdValue> + requires(unit == ::mp_units::one) +constexpr quantity& operator=(FwdValue&& v); +
    Effects: Equivalent to numerical-value = std​::​forward<FwdValue>(v).
    Returns: *this.

    5.6.6 Conversions [qty.conv]

    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, ToU{}), Rep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), Rep>{*this};
    template<RepresentationOf<quantity_spec> ToRep> + requires QuantityConvertibleTo<quantity, quantity<reference, ToRep>> +constexpr QuantityOf<quantity_spec> auto in() const; +
    Effects: Equivalent to: +return quantity<reference, ToRep>{*this};
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires QuantityConvertibleTo<quantity, + quantity<make-reference(quantity_spec, ToU{}), ToRep>> +constexpr QuantityOf<quantity_spec> auto in(ToU) const; +
    Effects: Equivalent to: +return quantity<make-reference(quantity_spec, ToU{}), ToRep>{*this}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}>(*this);
    template<RepresentationOf<quantity_spec> ToRep> + requires requires(const quantity q) { value_cast<ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in() const; +
    Effects: Equivalent to: +return value_cast<ToRep>(*this);
    template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires requires(const quantity q) { value_cast<ToU{}, ToRep>(q); } +constexpr QuantityOf<quantity_spec> auto force_in(ToU) const; +
    Effects: Equivalent to: +return value_cast<ToU{}, ToRep>(*this);

    5.6.7 Numerical value observers [qty.obs]

    template<Unit U> + requires(equivalent(U{}, unit)) +constexpr rep& numerical_value_ref_in(U) & noexcept; +template<Unit U> + requires(equivalent(U{}, unit)) +constexpr const rep& numerical_value_ref_in(U) const & noexcept; +
    Returns: numerical-value.
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires QuantityConvertibleTo<quantity, quantity<make-reference(quantity_spec, U{}), Rep>> +constexpr rep numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).in(U{}).numerical-value;
    template<UnitCompatibleWith<unit, quantity_spec> U> + requires requires(const quantity q) { value_cast<U{}>(q); } +constexpr rep force_numerical_value_in(U) const noexcept; +
    Effects: Equivalent to: +return (*this).force_in(U{}).numerical-value;

    5.6.8 Conversion operations [qty.conv.ops]

    template<typename V_, std::constructible_from<Rep> Value = std::remove_cvref_t<V_>> + requires(unit == ::mp_units::one) +explicit operator V_() const & noexcept; +
    Returns: numerical-value.
    template<typename Q_, QuantityLike Q = std::remove_cvref_t<Q_>> + requires QuantityConvertibleTo<quantity, quantity-like-type<Q>> +constexpr explicit(see below) operator Q_() const noexcept(see below); +
    Effects: Equivalent to: +return quantity_like_traits<Q>::from_numerical_value( + numerical_value_in(get_unit(quantity_like_traits<Q>::reference))); +
    Remarks: The expression inside explicit is equivalent to: +quantity_like_traits<Q>::explicit_export || + !std::convertible_to<Rep, typename quantity_like_traits<Q>::rep> +
    +The exception specification is equivalent to: +noexcept(quantity_like_traits<Q>::from_numerical_value(numerical-value)) && + std::is_nothrow_copy_constructible_v<rep> +

    5.6.9 Unary operations [qty.unary.ops]

    In the following descriptions, +let @ be the operator.
    constexpr QuantityOf<quantity_spec> auto operator+() const + requires see below; +constexpr QuantityOf<quantity_spec> auto operator-() const + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{@numerical-value, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(const rep v) { + { @v } -> std::common_with<rep>; +} +
    template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator++(Q&& q) + requires see below; +template<Mutable<quantity> Q> +friend constexpr decltype(auto) operator--(Q&& q) + requires see below; +
    Effects: Equivalent to +@q.numerical-value.
    Returns: std​::​forward<Q>(q).
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { @v } -> std::same_as<rep&>; +} +
    constexpr QuantityOf<quantity_spec> auto operator++(int) + requires see below; +constexpr QuantityOf<quantity_spec> auto operator--(int) + requires see below; +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{numerical-value@, reference};
    Remarks: The expression in the requires-clause is equivalent to: +requires(rep& v) { + { v@ } -> std::common_with<rep>; +} +

    5.6.10 Compound assignment operations [qty.assign.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity<R2, Rep2>& rhs); +template<Mutable<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is %=, then is_neq_zero(rhs) is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.in(lhs.unit).numerical-value.
    Returns: std​::​forward<Q>(lhs).
    Remarks: Let C be +
    • (!treat_as_floating_point<rep>) if @ is %=, and
    • true otherwise.
    +The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity> && C && +requires(rep& a, const Rep2 b) { + { a @ b } -> std::same_as<rep&>; +} +
    Recommended practice: If equivalent(unit, get_unit(rhs.reference)) is true, +then the expression rhs.in(lhs.unit) is replaced with rhs.
    template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& rhs); +template<Mutable<quantity> Q, ValuePreservingTo<Rep> Value> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& rhs); +
    Preconditions: If @ is /=, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to +lhs.numerical-value @ rhs.
    Returns: std​::​forward<Q>(lhs).
    Remarks: The expression in the requires-clause is equivalent to: +(!Quantity<Value>) && requires(rep& a, const Value b) { + { a @ b } -> std::same_as<rep&>; +} +
    template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator*=(Q&& lhs, const Q2& rhs); +template<Mutable<quantity> Q, QuantityOf<dimensionless> Q2> + requires see below +friend constexpr decltype(auto) operator/=(Q&& lhs, const Q2& rhs); +
    Effects: Equivalent to: +return std​::​forward<Q>(lhs) @ rhs.numerical-value;
    Remarks: The expression in the requires-clause is equivalent to: +(Q2::unit == ::mp_units::one) && ValuePreservingTo<typename Q2::rep, Rep> && +requires(rep& a, const Q2::rep b) { + { a @ b } -> std::same_as<rep&>; +} +

    5.6.11 Arithmetic operations [qty.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::plus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator+(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires CommonlyInvocableQuantities<std::minus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator-(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires(!treat_as_floating_point<Rep>) && (!treat_as_floating_point<Rep2>) && + CommonlyInvocableQuantities<std::modulus<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator%(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let F be the first argument to CommonlyInvocableQuantities.
    Preconditions: If @ is %, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +using ret = common-quantity-for<F, quantity, quantity<R2, Rep2>>; +const ret ret_lhs(lhs); +const ret ret_rhs(rhs); +return ::mp_units::quantity{ + ret_lhs.numerical_value_ref_in(ret::unit) @ ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; +
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Q& lhs, const Value& rhs); +
    Effects: Equivalent to: +return lhs @ ​::​mp_units​::​quantity{rhs};
    template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::plus<>, Rep, const Value&> +friend constexpr Quantity auto operator+(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::minus<>, Rep, const Value&> +friend constexpr Quantity auto operator-(const Value& lhs, const Q& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires(Q::unit == ::mp_units::one) && + InvokeResultOf<quantity_spec, std::modulus<>, Rep, const Value&> +friend constexpr Quantity auto operator%(const Value& lhs, const Q& rhs); +
    Effects: Equivalent to: +return ​::​mp_units​::​quantity{lhs} @ rhs;
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::multiplies<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator*(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires InvocableQuantities<std::divides<>, quantity, quantity<R2, Rep2>> +friend constexpr Quantity auto operator/(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{ + lhs.numerical_value_ref_in(unit) @ rhs.numerical_value_ref_in(rhs.unit), R @ R2}; +
    template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, typename Value> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, Rep, const Value&> +friend constexpr QuantityOf<quantity_spec> auto operator/(const Q& lhs, const Value& rhs); +
    Preconditions: If @ is /, then rhs != representation_values<Value>​::​zero() is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs.numerical_value_ref_in(unit) @ rhs, R}; +
    template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::multiplies<>, const Value&, Rep> +friend constexpr QuantityOf<quantity_spec> auto operator*(const Value& lhs, const Q& rhs); +template<typename Value, std::derived_from<quantity> Q> + requires(!Quantity<Value>) && (!Reference<Value>) && + InvokeResultOf<quantity_spec, std::divides<>, const Value&, Rep> +friend constexpr Quantity auto operator/(const Value& lhs, const Q& rhs); +
    Preconditions: If @ is /, then is_neq_zero(rhs) is true.
    Effects: Equivalent to: +return ::mp_units::quantity{lhs @ rhs.numerical_value_ref_in(unit), ::mp_units::one @ R}; +

    5.6.12 Comparison [qty.cmp]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr bool operator==(const Q& lhs, const quantity<R2, Rep2>& rhs); +template<std::derived_from<quantity> Q, auto R2, typename Rep2> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const quantity<R2, Rep2>& rhs); +
    Let C be +std​::​equality_comparable if @ is ==, and +std​::​three_way_comparable if @ is <=>.
    Effects: Equivalent to: +using ct = std::common_type_t<quantity, quantity<R2, Rep2>>; +const ct ct_lhs(lhs); +const ct ct_rhs(rhs); +return ct_lhs.numerical_value_ref_in(ct::unit) @ ct_rhs.numerical_value_ref_in(ct::unit); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { + typename std::common_type_t<quantity, quantity<R2, Rep2>>; +} && C<typename std::common_type_t<quantity, quantity<R2, Rep2>>::rep> +
    template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr bool operator==(const Q& lhs, const Value& rhs); +template<std::derived_from<quantity> Q, Representation Value> + requires see below +friend constexpr auto operator<=>(const Q& lhs, const Value& rhs); +
    Let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Returns: lhs.numerical_value_ref_in(unit) @ rhs.
    Remarks: The expression in the requires-clause is equivalent to: +(Q::unit == ::mp_units::one) && C<Rep, Value> +

    5.6.13 Value comparison [qty.val.cmp]

    friend constexpr bool is_eq_zero(const quantity& q) requires see below; +friend constexpr bool is_neq_zero(const quantity& q) requires see below; +friend constexpr bool is_lt_zero(const quantity& q) requires see below; +friend constexpr bool is_gt_zero(const quantity& q) requires see below; +friend constexpr bool is_lteq_zero(const quantity& q) requires see below; +friend constexpr bool is_gteq_zero(const quantity& q) requires see below; +
    Let is_F_zero be the function name.
    Returns:
    Remarks: Let C be +std​::​equality_comparable_with if F is eq or neq, and +std​::​three_way_comparable_with otherwise.
    The expression in the requires-clause is equivalent to: +requires { + { T::zero() } -> C<quantity>; +} +

    5.6.14 Construction helper delta [qty.delta]

    namespace mp_units { + +template<Reference R> +struct delta_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity{std​::​forward<FwdRep>(lhs), R{}};

    5.6.15 Non-member conversions [qty.non.mem.conv]

    template<Quantity To, typename FwdFrom, Quantity From = std::remove_cvref_t<FwdFrom>> + requires see below +constexpr To sudo-cast(FwdFrom&& q); // exposition only +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToU)) +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), typename Q::rep>>( + std::forward<FwdQ>(q)); +
    template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires RepresentationOf<ToRep, Q::quantity_spec> && + std::constructible_from<ToRep, typename Q::rep> +constexpr quantity<Q::reference, ToRep> value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<Q::reference, ToRep>>(std::forward<FwdQ>(q)); +
    template<Unit auto ToU, Representation ToRep, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +template<Representation ToRep, Unit auto ToU, typename FwdQ, + Quantity Q = std::remove_cvref_t<FwdQ>> + requires see below +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: +return sudo-cast<quantity<make-reference(Q::quantity_spec, ToU), ToRep>>( + std::forward<FwdQ>(q)); +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec> && +std::constructible_from<ToRep, typename Q::rep> +
    template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires(convertible(Q::reference, ToQ::unit)) && (ToQ::quantity_spec == Q::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename Q::rep> +constexpr Quantity auto value_cast(FwdQ&& q); +
    Effects: Equivalent to: return sudo-cast<ToQ>(std​::​forward<FwdQ>(q));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    [Example 1: auto length = isq::length(42 * m); +auto distance = quantity_cast<isq::distance>(length); + — end example]
    template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>> + requires QuantitySpecCastableTo<Q::quantity_spec, ToQS> +constexpr Quantity auto quantity_cast(FwdQ&& q); +
    Effects: Equivalent to: +return quantity{std::forward<FwdQ>(q).numerical-value, make-reference(ToQS, Q::unit)}; +

    5.6.16 std​::​common_type specializations [qty.common.type]

    template<mp_units::Quantity Q1, mp_units::Quantity Q2> + requires requires { + { mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference; + typename std::common_type_t<typename Q1::rep, typename Q2::rep>; + requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>, + mp_units::get_common_quantity_spec(Q1::quantity_spec, + Q2::quantity_spec)>; + } +struct std::common_type<Q1, Q2> { + using type = mp_units::quantity<mp_units::get_common_reference(Q1::reference, Q2::reference), + std::common_type_t<typename Q1::rep, typename Q2::rep>>; +}; + +template<mp_units::Quantity Q, mp_units::Representation Value> + requires(Q::unit == mp_units::one) && requires { + typename mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; + } +struct std::common_type<Q, Value> { + using type = mp_units::quantity<Q::reference, std::common_type_t<typename Q::rep, Value>>; +}; +

    5.7 Quantity point [qty.pt]

    5.7.1 General [qty.pt.general]

    Subclause [qty.pt] describes the class template quantity_point +that represents the value of a quantity (IEC 60050, 112-01-28) +that is an element of an affine space (IEC 60050, 102-03-02,102-04-01).

    5.7.2 Point origin [qty.pt.orig]

    5.7.2.1 General [qty.pt.orig.general]

    This subclause specifies the components +for defining the origin of an affine space.
    An origin is a point from which measurements (IEC 60050, 112-04-01) take place.

    5.7.2.2 Concepts [qty.pt.orig.concepts]

    template<typename T> +concept PointOrigin = SymbolicConstant<T> && std::derived_from<T, point-origin-interface>; + +template<typename T, auto QS> +concept PointOriginFor = PointOrigin<T> && QuantitySpecOf<decltype(QS), T::quantity-spec>; + +template<typename T, auto V> +concept SameAbsolutePointOriginAs = // exposition only + PointOrigin<T> && PointOrigin<decltype(V)> && same-absolute-point-origins(T{}, V); +

    5.7.2.3 Types [qty.pt.orig.types]

    5.7.2.3.1 Absolute [qty.abs.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct absolute_point_origin : point-origin-interface { + static constexpr QuantitySpec auto quantity-spec = QS; // exposition only +}; + +} +
    An absolute origin is an origin +chosen by convention and not defined in terms of another origin.
    A specialization of absolute_point_origin is used as a base type when defining an absolute origin.
    QS is the quantity the origin represents.

    5.7.2.3.2 Relative [qty.rel.pt.orig]

    namespace mp_units { + +template<QuantityPoint auto QP> +struct relative_point_origin : point-origin-interface { + static constexpr QuantityPoint auto quantity-point = QP; // exposition only + static constexpr QuantitySpec auto quantity-spec = see below; // exposition only + static constexpr PointOrigin auto absolute-point-origin = // exposition only + QP.absolute_point_origin; +}; + +} +
    A relative origin is an origin +of a subspace (IEC 60050, 102-03-03).
    A specialization of relative_point_origin is used as a base type when defining a relative origin O.
    O is offset from QP.absolute_point_origin by QP.quantity_from_zero().
    The member quantity-spec is equal to +QP.point_origin.quantity-spec if +QuantityKindSpec<decltype(auto(QP.quantity-spec))> + +is satisfied, and +to QP.quantity-spec otherwise.

    5.7.2.3.3 Zeroth [qty.zeroth.pt.orig]

    namespace mp_units { + +template<QuantitySpec auto QS> +struct zeroth_point_origin_ final : absolute_point_origin<QS> {}; + +} +
    zeroth_point_origin_<QS> represents an origin +chosen by convention as the value 0 of the quantity QS.

    5.7.2.4 Operations [qty.pt.orig.ops]

    namespace mp_units { + +struct point-origin-interface { + template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); + template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); + + template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> + friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; + + template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below + friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); + + template<PointOrigin PO1, PointOrigin PO2> + friend consteval bool operator==(PO1 po1, PO2 po2); +}; + +} +
    template<PointOrigin PO, typename FwdQ, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q); +template<Quantity FwdQ, PointOrigin PO, + QuantityOf<PO::quantity-spec> Q = std::remove_cvref_t<FwdQ>> +friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO); +
    Effects: Equivalent to: +return quantity_point{std​::​forward<FwdQ>(q), PO{}};
    template<PointOrigin PO, Quantity Q> + requires ReferenceOf<decltype(auto(Q::reference)), PO::quantity-spec> +friend constexpr QuantityPoint auto operator-(PO po, const Q& q) + requires requires { -q; }; +
    Effects: Equivalent to: +return po + -q;
    template<PointOrigin PO1, SameAbsolutePointOriginAs<PO1{}> PO2> + requires see below +friend constexpr Quantity auto operator-(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>()) { + return po1 - po2.quantity-point; +} else if constexpr (is-derived-from-specialization-of<PO2, absolute_point_origin>()) { + return po1.quantity-point - po2; +} else { + return po1.quantity-point - po2.quantity-point; +} +
    Remarks: The expression in the requires-clause is equivalent to: +QuantitySpecOf<decltype(auto(PO1::quantity-spec)), PO2::quantity-spec> && + (is-derived-from-specialization-of<PO1, relative_point_origin>() || + is-derived-from-specialization-of<PO2, relative_point_origin>()) +
    template<PointOrigin PO1, PointOrigin PO2> +friend consteval bool operator==(PO1 po1, PO2 po2); +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return std::is_same_v<PO1, PO2> || + (is-specialization-of<PO1, zeroth_point_origin>() && + is-specialization-of<PO2, zeroth_point_origin>() && + interconvertible(po1.quantity-spec, po2.quantity-spec)); +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return PO1::quantity-point == PO2::quantity-point; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO1::quantity-point.quantity_from_zero()); +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return same-absolute-point-origins(po1, po2) && + is_eq_zero(PO2::quantity-point.quantity_from_zero()); +

    5.7.2.5 Utilities [qty.pt.orig.utils]

    5.7.2.5.1 Same absolute [qty.same.abs.pt.origs]

    template<PointOrigin PO1, PointOrigin PO2> +consteval bool same-absolute-point-origins(PO1 po1, PO2 po2); // exposition only +
    Effects: Equivalent to: +if constexpr (is-derived-from-specialization-of<PO1, absolute_point_origin>() && + is-derived-from-specialization-of<PO2, absolute_point_origin>()) + return po1 == po2; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>() && + is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1.absolute-point-origin == po2.absolute-point-origin; +else if constexpr (is-derived-from-specialization-of<PO1, relative_point_origin>()) + return po1.absolute-point-origin == po2; +else if constexpr (is-derived-from-specialization-of<PO2, relative_point_origin>()) + return po1 == po2.absolute-point-origin; +else + return false; +

    5.7.2.5.2 Default [qty.def.pt.orig]

    template<Reference R> +consteval PointOriginFor<get_quantity_spec(R{})> auto default_point_origin(R); +
    Effects: Equivalent to: +if constexpr (requires { get_unit(R{}).point-origin; }) + return get_unit(R{}).point-origin; +else + return zeroth_point_origin<get_quantity_spec(R{})>; +

    5.7.3 Interoperability [qty.pt.like]

    template<typename T> +concept QuantityPointLike = + !QuantityPoint<T> && + qty-like-impl<T, quantity_point_like_traits> && // see [qty.like] + requires { + typename quantity_point<quantity_point_like_traits<T>::reference, + quantity_point_like_traits<T>::point_origin, + typename quantity_point_like_traits<T>::rep>; + }; +

    5.7.4 Class template quantity_point [qty.pt.syn]

    namespace mp_units { + +template<typename T> +concept QuantityPoint = (is-derived-from-specialization-of<T, quantity_point>()); + +template<typename QP, auto V> +concept QuantityPointOf = + QuantityPoint<QP> && (QuantitySpecOf<decltype(auto(QP::quantity_spec)), V> || + SameAbsolutePointOriginAs<decltype(auto(QP::absolute_point_origin)), V>); + +template<Reference auto R, + PointOriginFor<get_quantity_spec(R)> auto PO = default_point_origin(R), + RepresentationOf<get_quantity_spec(R)> Rep = double> +class quantity_point { +public: + // member types and values + static constexpr Reference auto reference = R; + static constexpr QuantitySpec auto quantity_spec = get_quantity_spec(reference); + static constexpr Dimension auto dimension = quantity_spec.dimension; + static constexpr Unit auto unit = get_unit(reference); + static constexpr PointOrigin auto absolute_point_origin = see below; + static constexpr PointOrigin auto point_origin = PO; + using rep = Rep; + using quantity_type = quantity<reference, Rep>; + + quantity_type quantity-from-origin; // exposition only + + // [qty.pt.static], static member functions + static constexpr quantity_point min() noexcept + requires see below; + static constexpr quantity_point max() noexcept + requires see below; + + // [qty.pt.cons], constructors and assignment + + quantity_point() = default; + quantity_point(const quantity_point&) = default; + quantity_point(quantity_point&&) = default; + ~quantity_point() = default; + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) + constexpr explicit quantity_point(FwdQ&& q); + + template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> + constexpr quantity_point(FwdQ&& q, decltype(PO)); + + template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> + constexpr quantity_point(FwdQ&& q, PO2); + + template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> + constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); + + template<QuantityPointLike QP> + requires see below + constexpr explicit(see below) quantity_point(const QP& qp); + + quantity_point& operator=(const quantity_point&) = default; + quantity_point& operator=(quantity_point&&) = default; + + // [qty.pt.conv], conversions + + template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> + constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + + template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + template<RepresentationOf<quantity_spec> ToRep> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in() const; + + template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below + constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + + // [qty.pt.obs], quantity value observers + + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr quantity_type& quantity_ref_from(PO2) & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; + template<PointOrigin PO2> + requires(PO2{} == point_origin) + void quantity_ref_from(PO2) const && = delete; + + template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } + constexpr Quantity auto quantity_from(PO2) const; + + template<QuantityPointOf<absolute_point_origin> QP> + constexpr Quantity auto quantity_from(const QP&) const; + + constexpr Quantity auto quantity_from_zero() const; + + // [qty.pt.conv.ops], conversion operations + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() const & noexcept(see below); + template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below + constexpr explicit(see below) operator QP_() && noexcept(see below); + + // [qty.pt.unary.ops], unary operations + + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; + template<Mutable<quantity_point> QP> + friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; + + constexpr quantity_point operator++(int) + requires see below; + constexpr quantity_point operator--(int) + requires see below; + + // [qty.pt.assign.ops], compound assignment operations + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); + template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below + friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); + + // [qty.pt.arith.ops], arithmetic operations + + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; + template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> + friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; + + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; + + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(const QP& qp, PO2 po); + template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below + friend constexpr Quantity auto operator-(PO2 po, const QP& qp); + + // [qty.pt.cmp], comparison + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr bool operator==(const QP& lhs, const QP2& rhs); + template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below + friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +}; + +template<Quantity Q> +explicit quantity_point(Q q) + -> quantity_point<Q::reference, default_point_origin(Q::reference), typename Q::rep>; + +template<Quantity Q, PointOriginFor<Q::quantity_spec> PO> +quantity_point(Q, PO) -> quantity_point<Q::reference, PO{}, typename Q::rep>; + +template<QuantityPointLike QP, typename Traits = quantity_point_like_traits<QP>> +explicit(quantity_point_like_traits<QP>::explicit_import) quantity_point(QP) + -> quantity_point<Traits::reference, Traits::point_origin, typename Traits::rep>; + +} +
    quantity_point<R, PO, Rep> is a structural type (N4971, [temp.param]) +if Rep is a structural type.
    The member absolute_point_origin is equal to PO if +is-derived-from-specialization-of<decltype(PO), absolute_point_origin>() + +is true, and +to PO.quantity-point.absolute_point_origin otherwise.

    5.7.5 Static member functions [qty.pt.static]

    static constexpr quantity_point min() noexcept + requires see below; +static constexpr quantity_point max() noexcept + requires see below; +
    Let F be one of min and max.
    Returns: {quantity_type​::​F(), PO}.
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity_type::F(); } +

    5.7.6 Constructors [qty.pt.cons]

    template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && + (point_origin == default_point_origin(R)) && + (implicitly_convertible(Q::quantity_spec, quantity_spec)) +constexpr explicit quantity_point(FwdQ&& q); + +template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> +constexpr quantity_point(FwdQ&& q, decltype(PO)); +
    Effects: Initializes quantity-from-origin with std​::​forward<FwdQ>(q).
    template<typename FwdQ, PointOrigin PO2, + QuantityOf<PO2::quantity-spec> Q = std::remove_cvref_t<FwdQ>> + requires std::constructible_from<quantity_type, FwdQ> && SameAbsolutePointOriginAs<PO2, PO> +constexpr quantity_point(FwdQ&& q, PO2); +
    Effects: Equivalent to: +quantity_point(quantity_point<Q::reference, PO2{}, typename Q::rep>{std::forward<FwdQ>(q), + PO2{}}) +
    template<QuantityPointOf<absolute_point_origin> QP> + requires std::constructible_from<quantity_type, typename QP::quantity_type> +constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) + quantity_point(const QP& qp); +
    Effects: If point_origin == QP​::​point_origin is true, +initializes quantity-from-origin with qp.quantity_ref_from(point_origin).
    Otherwise, initializes quantity-from-origin with qp - point_origin.
    template<QuantityPointLike QP> + requires see below +constexpr explicit(see below) quantity_point(const QP& qp); +
    Let Traits be quantity_point_like_traits<QP>.
    Effects: Initializes quantity-from-origin with +Traits::to_numerical_value(qp), get_unit(Traits::reference) +
    Remarks: The expression in the requires-clause is equivalent to: +(Traits::point_origin == point_origin) && + std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +
    +The expression inside explicit is equivalent to: +Traits::explicit_import || + !std::convertible_to<quantity<Traits::reference, typename Traits::rep>, quantity_type> +

    5.7.7 Conversions [qty.pt.conv]

    template<SameAbsolutePointOriginAs<absolute_point_origin> NewPO> +constexpr QuantityPointOf<(NewPO{})> auto point_for(NewPO new_origin) const; +
    Effects: Equivalent to: +if constexpr (std::is_same_v<NewPO, decltype(point_origin)>) + return *this; +else + return ::mp_units::quantity_point{*this - new_origin, new_origin}; +
    template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto in(ToU) const; + +template<UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; + +template<RepresentationOf<quantity_spec> ToRep> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in() const; + +template<RepresentationOf<quantity_spec> ToRep, + UnitCompatibleWith<unit, quantity_spec> ToU> + requires see below +constexpr QuantityPointOf<quantity_spec> auto force_in(ToU) const; +
    Let converted-quantity-expr be an expression denoting +the function call to the corresponding member of quantity_ref_from(point_origin).
    Effects: Equivalent to: +return ::mp_units::quantity_point{converted-quantity-expr, point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +requires { converted-quantity-expr; } +

    5.7.8 Quantity value observers [qty.pt.obs]

    template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr quantity_type& quantity_ref_from(PO2) & noexcept; +template<PointOrigin PO2> + requires(PO2{} == point_origin) +constexpr const quantity_type& quantity_ref_from(PO2) const & noexcept; +
    Returns: quantity-from-origin.
    template<PointOrigin PO2> + requires requires(const quantity_point qp) { qp - PO2{}; } +constexpr Quantity auto quantity_from(PO2 rhs) const; + +template<QuantityPointOf<absolute_point_origin> QP> +constexpr Quantity auto quantity_from(const QP& rhs) const; +
    Effects: Equivalent to: +return *this - rhs;
    constexpr Quantity auto quantity_from_zero() const; +
    Effects: Equivalent to: +if constexpr (requires { unit.point-origin; }) { + // can lose the input unit + const auto q = quantity_from(unit.point-origin); + if constexpr (requires { q.in(unit); }) + // restore the unit + return q.in(unit); + else + return q; +} else + return quantity_from(absolute_point_origin); +

    5.7.9 Conversion operations [qty.pt.conv.ops]

    template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() const & noexcept(see below); +template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>> + requires see below +constexpr explicit(see below) operator QP_() && noexcept(see below); +
    Let Traits be quantity_point_like_traits<QP>.
    Let result-expr be +Traits::from_numerical_value(std::move(quantity-from-origin).numerical-value) +
    Returns: result-expr.
    Remarks: The expression in the requires-clause is equivalent to: +(point_origin == Traits::point_origin) && + std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +The expression inside explicit is equivalent to: +Traits::explicit_export || + !std::convertible_to<quantity_type, quantity<Traits::reference, typename Traits::rep>> +
    +Let T be +std​::​is_nothrow_copy_constructible_v for the first signature, and +std​::​is_nothrow_move_constructible_v for the second signature.
    The exception specification is equivalent to: +noexcept(result-expr) && T<rep> +

    5.7.10 Unary operations [qty.pt.unary.ops]

    In the following descriptions, +let @ be the operator.
    template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator++(QP&& qp) + requires see below; +template<Mutable<quantity_point> QP> +friend constexpr decltype(auto) operator--(QP&& qp) + requires see below; +
    Effects: Equivalent to +@qp.quantity-from-origin.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +requires { @qp.quantity-from-origin; } +
    constexpr quantity_point operator++(int) + requires see below; +constexpr quantity_point operator--(int) + requires see below; +
    Effects: Equivalent to: +return {quantity-from-origin@, PO};
    Remarks: The expression in the requires-clause is equivalent to: +requires { quantity-from-origin@; } +

    5.7.11 Compound assignment operations [qty.pt.assign.ops]

    template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator+=(QP&& qp, const quantity<R2, Rep2>& q); +template<Mutable<quantity_point> QP, auto R2, typename Rep2> + requires see below +friend constexpr decltype(auto) operator-=(QP&& qp, const quantity<R2, Rep2>& q); +
    Let @ be the operator.
    Effects: Equivalent to +qp.quantity-from-origin @ q.
    Returns: std​::​forward<QP>(qp).
    Remarks: The expression in the requires-clause is equivalent to: +QuantityConvertibleTo<quantity<R2, Rep2>, quantity_type> && + requires { qp.quantity-from-origin @ q; } +

    5.7.12 Arithmetic operations [qty.pt.arith.ops]

    In the following descriptions, +let @ be the operator.
    template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator+(const quantity<R2, Rep2>& q, const QP& qp) + requires see below; +template<std::derived_from<quantity_point> QP, auto R2, typename Rep2> +friend constexpr QuantityPoint auto operator-(const QP& qp, const quantity<R2, Rep2>& q) + requires see below; +
    Effects: Equivalent to: +if constexpr (is-specialization-of<PO, zeroth_point_origin>()) + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q}; +else + return ::mp_units::quantity_point{qp.quantity_ref_from(PO) @ q, PO}; +
    Remarks: The expression in the requires-clause is equivalent to: +ReferenceOf<decltype(R2), PO.quantity-spec> && requires { + qp.quantity_ref_from(PO) @ q; +} +
    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> +friend constexpr Quantity auto operator-(const QP& lhs, const QP2& rhs) + requires see below; +
    Effects: Equivalent to: +return lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin) + + (lhs.point_origin - rhs.point_origin); +
    Remarks: The expression in the requires-clause is equivalent to: +requires { lhs.quantity_ref_from(point_origin) - rhs.quantity_ref_from(QP2::point_origin); } +
    Recommended practice: The subtraction of two equal origins is not evaluated.
    template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(const QP& qp, PO2 po); +template<std::derived_from<quantity_point> QP, PointOrigin PO2> + requires see below +friend constexpr Quantity auto operator-(PO2 po, const QP& qp); +
    Effects: For the first signature, +equivalent to: +if constexpr (point_origin == po) + return qp.quantity_ref_from(point_origin); +else if constexpr (is-derived-from-specialization-of<PO2, + ::mp_units::absolute_point_origin>()) { + return qp.quantity_ref_from(point_origin) + (qp.point_origin - qp.absolute_point_origin); +} else { + return qp.quantity_ref_from(point_origin) - + po.quantity-point.quantity_ref_from(po.quantity-point.point_origin) + + (qp.point_origin - po.quantity-point.point_origin); +} +
    +For the second signature, +equivalent to: return -(qp - po);
    Remarks: The expression in the requires-clause is equivalent to: +QuantityPointOf<quantity_point, PO2{}> && + ReferenceOf<decltype(auto(reference)), PO2::quantity-spec> +
    Recommended practice: The subtraction of two equal origins is not evaluated.

    5.7.13 Comparison [qty.pt.cmp]

    template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr bool operator==(const QP& lhs, const QP2& rhs); +template<std::derived_from<quantity_point> QP, QuantityPointOf<absolute_point_origin> QP2> + requires see below +friend constexpr auto operator<=>(const QP& lhs, const QP2& rhs); +
    Let @ be the operator, and +let C be +std​::​equality_comparable_with if @ is ==, and +std​::​three_way_comparable_with if @ is <=>.
    Effects: Equivalent to: +return lhs - lhs.absolute_point_origin @ rhs - rhs.absolute_point_origin; +
    Remarks: The expression in the requires-clause is equivalent to: +C<quantity_type, typename QP2::quantity_type> +
    Recommended practice: If the origins are equal, instead evaluate +lhs.quantity_ref_from(point_origin) @ rhs.quantity_ref_from(QP2::point_origin) +

    5.7.14 Construction helper point [qty.point]

    namespace mp_units { + +template<Reference R> +struct point_ { + template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> + constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +}; + +} +
    template<typename FwdRep, + RepresentationOf<get_quantity_spec(R{})> Rep = std::remove_cvref_t<FwdRep>> +constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const; +
    Effects: Equivalent to: +return quantity_point{quantity{std​::​forward<FwdRep>(lhs), R{}}};

    5.7.15 Non-member conversions [qty.pt.non.mem.conv]

    template<QuantityPoint ToQP, typename FwdFromQP, + QuantityPoint FromQP = std::remove_cvref_t<FwdFromQP>> + requires see below +constexpr QuantityPoint auto sudo-cast(FwdFromQP&& qp); +
    Returns: TBD.
    value_cast is an explicit cast that allows truncation.
    template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToU)) +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires RepresentationOf<ToRep, QP::quantity_spec> && + std::constructible_from<ToRep, typename QP::rep> +constexpr quantity_point<QP::reference, QP::point_origin, ToRep> value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return {value_cast<ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), QP::point_origin}; +
    template<Unit auto ToU, Representation ToRep, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +template<Representation ToRep, Unit auto ToU, typename FwdQP, + QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires see below +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToU, ToRep>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    Remarks: The expression in the requires-clause is equivalent to: +(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec> && +std::constructible_from<ToRep, typename QP::rep> +
    template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQ::unit)) && (ToQ::quantity_spec == QP::quantity_spec) && + std::constructible_from<typename ToQ::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return quantity_point{value_cast<ToQ>(std::forward<FwdQP>(qp).quantity-from-origin), + QP::point_origin}; +
    template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires(convertible(QP::reference, ToQP::unit)) && + (ToQP::quantity_spec == QP::quantity_spec) && + (same-absolute-point-origins(ToQP::point_origin, QP::point_origin)) && + std::constructible_from<typename ToQP::rep, typename QP::rep> +constexpr QuantityPoint auto value_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return sudo-cast<ToQP>(std​::​forward<FwdQP>(qp));
    quantity_cast is an explicit cast that allows converting to more specific quantities.
    template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>> + requires QuantitySpecCastableTo<QP::quantity_spec, ToQS> +constexpr QuantityPoint auto quantity_cast(FwdQP&& qp); +
    Effects: Equivalent to: +return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin), + QP::point_origin}; +

    5.9 std​::​chrono interoperability [qty.chrono]

    namespace mp_units { + +template<typename Period> +consteval auto time-unit-from-chrono-period() +{ + using namespace si; + + if constexpr (is_same_v<Period, std::chrono::nanoseconds::period>) + return nano<second>; + else if constexpr (is_same_v<Period, std::chrono::microseconds::period>) + return micro<second>; + else if constexpr (is_same_v<Period, std::chrono::milliseconds::period>) + return milli<second>; + else if constexpr (is_same_v<Period, std::chrono::seconds::period>) + return second; + else if constexpr (is_same_v<Period, std::chrono::minutes::period>) + return minute; + else if constexpr (is_same_v<Period, std::chrono::hours::period>) + return hour; + else if constexpr (is_same_v<Period, std::chrono::days::period>) + return day; + else if constexpr (is_same_v<Period, std::chrono::weeks::period>) + return mag<7> * day; + else + return mag_ratio<Period::num, Period::den> * second; +} + +template<typename Rep, typename Period> +struct quantity_like_traits<std::chrono::duration<Rep, Period>> { + static constexpr auto reference = time-unit-from-chrono-period<Period>(); + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = false; + using rep = Rep; + using T = std::chrono::duration<Rep, Period>; + + static constexpr rep to_numerical_value(const T& q) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return q.count(); + } + + static constexpr T from_numerical_value(const rep& v) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return T(v); + } +}; + +template<typename Clock> +struct chrono_point_origin_ final : absolute_point_origin<isq::time> { + using clock = Clock; +}; + +template<typename Clock, typename Rep, typename Period> +struct quantity_point_like_traits< + std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>> { + static constexpr auto reference = time-unit-from-chrono-period<Period>(); + static constexpr auto point_origin = chrono_point_origin<Clock>; + static constexpr bool explicit_import = false; + static constexpr bool explicit_export = false; + using rep = Rep; + using T = std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>; + + static constexpr rep to_numerical_value(const T& tp) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return tp.time_since_epoch().count(); + } + + static constexpr T from_numerical_value(const rep& v) noexcept( + std::is_nothrow_copy_constructible_v<rep>) + { + return T(std::chrono::duration<Rep, Period>(v)); + } +}; + +} +
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/quantities.summary.html b/HEAD/api_reference/gen/quantities.summary.html new file mode 100644 index 00000000..0214edae --- /dev/null +++ b/HEAD/api_reference/gen/quantities.summary.html @@ -0,0 +1,6 @@ +[quantities.summary]

    5 Quantities and units library [quantities]

    5.1 Summary [quantities.summary]

    This Clause describes components for dealing with quantities and units, +as summarized in Table 3.
    Table 3: Quantities and units library summary [tab:quantities.summary]
    Subclause
    Module
    Utilities
    mp_units.core
    Reference
    Representation
    Quantity
    Quantity point
    Systems
    mp_units.systems
    std​::​chrono interoperability
    +
    [Editor's note: +Following the SG16 recommendation at https://lists.isocpp.org/sg16/2024/10/4490.php, +the universal-character-names should be replaced by their UTF-8 code points. +]
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/refs.html b/HEAD/api_reference/gen/refs.html index 93db6388..2381e6c4 100644 --- a/HEAD/api_reference/gen/refs.html +++ b/HEAD/api_reference/gen/refs.html @@ -1,4 +1,4 @@ -[refs]

    2 References [refs]

    The following documents are referred to in the text +[refs]

    2 References [refs]

    The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document.
    For dated references, only the edition cited applies.
    For undated references, the latest edition of the referenced document @@ -6,4 +6,4 @@ the latest edition of the referenced document Amendment 3 — International Electrotechnical Vocabulary (IEV) — Part 102: Mathematics — General concepts and linear algebra
  • IEC 60050-112:2010/AMD2:2020, Amendment 2 — International Electrotechnical Vocabulary (IEV) — -Part 112: Quantities and units
  • ISO 80000 (all parts), Quantities and units
  • The C++ Standards Committee.
    N4971: Working Draft, Standard for Programming Language C++.
    Edited by Thomas Köppe.
    Available from: https://wg21.link/N4971
  • The C++ Standards Committee.
    SD-8: Standard Library Compatibility.
    Edited by Bryce Lelbach.
    Available from: https://wg21.link/SD8
  • \ No newline at end of file +Part 112: Quantities and units
  • ISO 80000 (all parts), Quantities and units
  • The C++ Standards Committee.
    N4971: Working Draft, Standard for Programming Language C++.
    Edited by Thomas Köppe.
    Available from: https://wg21.link/N4971
  • The C++ Standards Committee.
    P3094R5: std​::​basic_fixed_string.
    Edited by Mateusz Pusz.
  • The C++ Standards Committee.
    SD-8: Standard Library Compatibility.
    Edited by Bryce Lelbach.
    Available from: https://wg21.link/SD8
  • \ No newline at end of file diff --git a/HEAD/api_reference/gen/scope.html b/HEAD/api_reference/gen/scope.html index b86e6f6a..b70e2797 100644 --- a/HEAD/api_reference/gen/scope.html +++ b/HEAD/api_reference/gen/scope.html @@ -1 +1 @@ -[scope]

    1 Scope [scope]

    This document describes the contents of the mp-units library.
    \ No newline at end of file +[scope]

    1 Scope [scope]

    This document describes the contents of the mp-units library.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/spec.cats.html b/HEAD/api_reference/gen/spec.cats.html index 561fbe2a..3093b898 100644 --- a/HEAD/api_reference/gen/spec.cats.html +++ b/HEAD/api_reference/gen/spec.cats.html @@ -1,4 +1,4 @@ -[spec.cats]

    4 Specification [spec]

    4.2 Categories [spec.cats]

    Detailed specifications for each of the components in the library are in -[qties]–[qties], -as shown in Table 1.
    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    The quantities library ([qties]) +[spec.cats]

    4 Specification [spec]

    4.2 Categories [spec.cats]

    Detailed specifications for each of the components in the library are in +[quantities]–[quantities], +as shown in Table 1.
    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    The quantities library ([quantities]) describes components for dealing with quantities.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/spec.ext.html b/HEAD/api_reference/gen/spec.ext.html index 1cf3c828..fc62a996 100644 --- a/HEAD/api_reference/gen/spec.ext.html +++ b/HEAD/api_reference/gen/spec.ext.html @@ -1,6 +1,6 @@ -[spec.ext]

    4 Specification [spec]

    4.1 External [spec.ext]

    The specification of the mp-units library subsumes +[spec.ext]

    4 Specification [spec]

    4.1 External [spec.ext]

    The specification of the mp-units library subsumes N4971, [description], N4971, [requirements], N4971, [concepts.equality], and SD-8, all assumingly amended for the context of this library.
    [Note 1: 
    This means that, non exhaustively,
    • ​::​mp_units2 is a reserved namespace, and
    • std​::​vector<mp_units​::​type> is a program-defined specialization and a library-defined specialization -from the point of view of the C++ standard library and the mp-units library, respectively.
    — end note]
    The mp-units library is not part of the C++ implementation.
    \ No newline at end of file +from the point of view of the C++ standard library and the mp-units library, respectively.
    — end note]
    The mp-units library is not part of the C++ implementation.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/spec.html b/HEAD/api_reference/gen/spec.html index 5c897797..0142d10e 100644 --- a/HEAD/api_reference/gen/spec.html +++ b/HEAD/api_reference/gen/spec.html @@ -1,12 +1,12 @@ -[spec]

    4 Specification [spec]

    4.1 External [spec.ext]

    The specification of the mp-units library subsumes +[spec]

    4 Specification [spec]

    4.1 External [spec.ext]

    The specification of the mp-units library subsumes N4971, [description], N4971, [requirements], N4971, [concepts.equality], and SD-8, all assumingly amended for the context of this library.
    [Note 1: 
    This means that, non exhaustively,
    • ​::​mp_units2 is a reserved namespace, and
    • std​::​vector<mp_units​::​type> is a program-defined specialization and a library-defined specialization -from the point of view of the C++ standard library and the mp-units library, respectively.
    — end note]
    The mp-units library is not part of the C++ implementation.

    4.2 Categories [spec.cats]

    Detailed specifications for each of the components in the library are in -[qties]–[qties], -as shown in Table 1.
    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    The quantities library ([qties]) -describes components for dealing with quantities.

    4.3 Modules [spec.mods]

    The mp-units library provides the +from the point of view of the C++ standard library and the mp-units library, respectively.
    — end note]
    The mp-units library is not part of the C++ implementation.

    4.2 Categories [spec.cats]

    Detailed specifications for each of the components in the library are in +[quantities]–[quantities], +as shown in Table 1.
    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    The quantities library ([quantities]) +describes components for dealing with quantities.

    4.3 Modules [spec.mods]

    The mp-units library provides the mp-units modules, -shown in Table 2.
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with +shown in Table 2.
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with MP_UNITSdigit-sequence_.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/spec.mods.html b/HEAD/api_reference/gen/spec.mods.html index e875280e..6b31e427 100644 --- a/HEAD/api_reference/gen/spec.mods.html +++ b/HEAD/api_reference/gen/spec.mods.html @@ -1,3 +1,3 @@ -[spec.mods]

    4 Specification [spec]

    4.3 Modules [spec.mods]

    The mp-units library provides the +[spec.mods]

    4 Specification [spec]

    4.3 Modules [spec.mods]

    The mp-units library provides the mp-units modules, shown in Table 2.
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/spec.reqs.html b/HEAD/api_reference/gen/spec.reqs.html index 86818241..87d37247 100644 --- a/HEAD/api_reference/gen/spec.reqs.html +++ b/HEAD/api_reference/gen/spec.reqs.html @@ -1,2 +1,2 @@ -[spec.reqs]

    4 Specification [spec]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with +[spec.reqs]

    4 Specification [spec]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with MP_UNITSdigit-sequence_.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/spec.res.names.html b/HEAD/api_reference/gen/spec.res.names.html index 5a68bb16..a17d22a7 100644 --- a/HEAD/api_reference/gen/spec.res.names.html +++ b/HEAD/api_reference/gen/spec.res.names.html @@ -1,2 +1,2 @@ -[spec.res.names]

    4 Specification [spec]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with +[spec.res.names]

    4 Specification [spec]

    4.4 Library-wide requirements [spec.reqs]

    4.4.1 Reserved names [spec.res.names]

    The mp-units library reserves macro names that start with MP_UNITSdigit-sequence_.
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/tab.html b/HEAD/api_reference/gen/tab.html index dfafefd4..430cedf8 100644 --- a/HEAD/api_reference/gen/tab.html +++ b/HEAD/api_reference/gen/tab.html @@ -1 +1 @@ -14882: Tables

    Tables [tab]

    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems
    Table 3: Quantities library summary [tab:qties.summary]
    Subclause
    Module
    Helpers
    mp_units.core
    Traits
    Concepts
    Types
    Compatibility
    Dimension one
    Systems
    mp_units.systems
    std​::​chrono compatibility
    \ No newline at end of file +14882: Tables

    Tables [tab]

    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    Table 2: mp-units modules [tab:modules]
    mp_units
    mp_units.core
    mp_units.systems
    Table 3: Quantities and units library summary [tab:quantities.summary]
    Subclause
    Module
    Utilities
    mp_units.core
    Reference
    Representation
    Quantity
    Quantity point
    Systems
    mp_units.systems
    std​::​chrono interoperability
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/tab:lib.cats.html b/HEAD/api_reference/gen/tab:lib.cats.html index 235357d0..8b6ee1e8 100644 --- a/HEAD/api_reference/gen/tab:lib.cats.html +++ b/HEAD/api_reference/gen/tab:lib.cats.html @@ -1 +1 @@ -[tab:lib.cats]

    4 Specification [spec]

    4.2 Categories [spec.cats]

    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    \ No newline at end of file +[tab:lib.cats]

    4 Specification [spec]

    4.2 Categories [spec.cats]

    Table 1: Library categories [tab:lib.cats]
    Clause
    Category
    Quantities library
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/tab:qties.summary.html b/HEAD/api_reference/gen/tab:qties.summary.html deleted file mode 100644 index 7d3ebefa..00000000 --- a/HEAD/api_reference/gen/tab:qties.summary.html +++ /dev/null @@ -1 +0,0 @@ -[tab:qties.summary]

    5 Quantities library [qties]

    5.1 Summary [qties.summary]

    Table 3: Quantities library summary [tab:qties.summary]
    Subclause
    Module
    Helpers
    mp_units.core
    Traits
    Concepts
    Types
    Compatibility
    Dimension one
    Systems
    mp_units.systems
    std​::​chrono compatibility
    \ No newline at end of file diff --git a/HEAD/api_reference/gen/tab:quantities.summary.html b/HEAD/api_reference/gen/tab:quantities.summary.html new file mode 100644 index 00000000..00a3b0ed --- /dev/null +++ b/HEAD/api_reference/gen/tab:quantities.summary.html @@ -0,0 +1 @@ +[tab:quantities.summary]

    5 Quantities and units library [quantities]

    5.1 Summary [quantities.summary]

    Table 3: Quantities and units library summary [tab:quantities.summary]
    Subclause
    Module
    Utilities
    mp_units.core
    Reference
    Representation
    Quantity
    Quantity point
    Systems
    mp_units.systems
    std​::​chrono interoperability
    \ No newline at end of file diff --git a/HEAD/feed_json_created.json b/HEAD/feed_json_created.json index 8df6e9a8..116c6084 100644 --- a/HEAD/feed_json_created.json +++ b/HEAD/feed_json_created.json @@ -1 +1 @@ -{"version": "https://jsonfeed.org/version/1", "title": "mp-units", "home_page_url": "https://mpusz.github.io/mp-units/HEAD/", "feed_url": "https://mpusz.github.io/mp-units/HEAD/feed_json_created.json", "description": "The quantities and units library for C++", "icon": null, "authors": [{"name": "mp-units Team"}], "language": "en", "items": [{"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "title": "Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting

    \n

    The Wroc\u0142aw 2024 meeting was another efficient step in the standardization of this library.\nWe've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.\nWe've also introduced std::fixed_string to LEWG for C++26.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/25/report-from-the-wroc\u0142aw-2024-iso-c-committee-meeting.png", "date_published": "2024-11-25T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "title": "International System of Quantities (ISQ): Part 6 - Challenges", "content_html": "

    International System of Quantities (ISQ): Part 6 - Challenges

    \n

    This article might be the last one from our series. This time, we will discuss the challenges and\nissues with modeling of the ISQ in software.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges.png", "date_published": "2024-11-11T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "title": "mp-units 2.4.0 released!", "content_html": "

    mp-units 2.4.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release was unexpected. We planned a significant new feature to happen next, but while\npreparing for it, and also while writing API Reference documentation, we made so many vital fixes\nand improvements that we decided that they deserve a dedicated release first.

    \n

    This post describes the most significant improvements while a much longer list of the changes\nintroduced by the new version can be found in our Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/05/mp-units-240-released.png", "date_published": "2024-11-05T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "title": "International System of Quantities (ISQ): Part 5 - Benefits", "content_html": "

    International System of Quantities (ISQ): Part 5 - Benefits

    \n

    In the previous articles, we introduced the International System of Quantities, described how we\ncan model and implement it in a programming language, and presented the issues of software that\ndoes not use such abstraction to implement a units library.

    \n

    Some of the issues raised in Part 2 of our series\nwere addressed in Part 3 already. This article will present\nhow our ISQ model elegantly addresses the remaining problems.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits.png", "date_published": "2024-11-04T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "title": "International System of Quantities (ISQ): Part 4 - Implementing ISQ", "content_html": "

    International System of Quantities (ISQ): Part 4 - Implementing ISQ

    \n

    Up until now, we have introduced the International System of Quantities and described how we can\nmodel its main aspects. This article will present how to implement those models in a programming\nlanguage, and we will point out some of the first issues that stand in our way.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq.png", "date_published": "2024-10-28T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "title": "International System of Quantities (ISQ): Part 3 - Modeling ISQ", "content_html": "

    International System of Quantities (ISQ): Part 3 - Modeling ISQ

    \n

    The physical units libraries on the market typically only focus on modeling one or more systems\nof units. However, as we have learned, this is not the only system kind to model. Another,\nand maybe even more important, is a system of quantities. The most important example here is\nthe International System of Quantities (ISQ) defined by ISO/IEC 80000.

    \n

    This article continues our series about the International System of Quantities. This time, we will\nlearn about the main ideas behind the ISQ and describe how it can be modelled in a programming\nlanguage.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq.png", "date_published": "2024-10-21T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "title": "International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used", "content_html": "

    International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used

    \n

    This article is the next one in our series about the ISQ. After introducing the basic terms and\nsystems, this article will talk about the issues we face when we base the quantities and units\nlibrary on just units or dimensions.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used.png", "date_published": "2024-10-14T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "title": "International System of Quantities (ISQ): Part 1 - Introduction", "content_html": "

    International System of Quantities (ISQ): Part 1 - Introduction

    \n

    This post starts a series of articles about the International System of Quantities (ISQ).\nIn this series, we will describe:

    \n
      \n
    • What is ISQ?
    • \n
    • Which engineering problems does ISQ help to solve and how?
    • \n
    • How to model and implement it in the programming language?
    • \n
    • What is missing in the ISQ, and why is that a problem?
    • \n
    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction.png", "date_published": "2024-10-07T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "title": "mp-units 2.3.0 released!", "content_html": "

    mp-units 2.3.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release fine-tunes many key features of the library. This post describes the most interesting\nimprovements, while a much longer list of the changes introduced by the new version can be found in\nour Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/09/27/mp-units-230-released.png", "date_published": "2024-09-27T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "title": "Report from the St. Louis 2024 ISO C++ Committee meeting", "content_html": "

    Report from the St. Louis 2024 ISO C++ Committee meeting

    \n

    We made significant progress in the standardization of this library during the ISO C++ Committee\nmeeting in St. Louis.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting.png", "date_published": "2024-07-02T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "title": "mp-units 2.2.0 released!", "content_html": "

    mp-units 2.2.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    Among other features, this release provides long-awaited support for C++20 modules, redesigns and\nenhances text output formatting, and greatly simplifies quantity point usage. This post describes\nthose and a few other smaller interesting improvements, while a much longer list of the most\nsignificant changes introduced by the new version can be found in our\nRelease Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/06/14/mp-units-220-released.png", "date_published": "2024-06-14T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "title": "Report from the Tokyo 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Tokyo 2024 ISO C++ Committee meeting

    \n

    The Tokyo 2024 meeting was a very important step in the standardization of this library. Several\nWG21 groups reviewed proposals, and the feedback was really good.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting.png", "date_published": "2024-04-15T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "title": "mp-units 2.1.0 released!", "content_html": "

    mp-units 2.1.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe the most important of them\nin this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/12/09/mp-units-210-released.png", "date_published": "2023-12-09T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "title": "Report from the Kona 2023 ISO C++ Committee meeting", "content_html": "

    Report from the Kona 2023 ISO C++ Committee meeting

    \n

    Several groups in the ISO C++ Committee reviewed the P1935: A C++ Approach to Physical Units\nproposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potential\nstandardization of such a library and encouraged further work. The authors also got valuable\ninitial feedback that highly influenced the design of the V2 version of the mp-units library.

    \n

    In the following years, we scoped on getting more feedback from the production and design. This\nresulted in version 2 of the mp-units library that resolved many issues the users and Committee\nmembers raised. The features and interfaces of this version are close to being the best we can get\nwith the current version of the C++ language standard.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting.png", "date_published": "2023-11-12T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "title": "What's new in mp-units 2.0?", "content_html": "

    What's new in mp-units 2.0?

    \n

    After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe some of them in this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/09/24/whats-new-in-mp-units-20.png", "date_published": "2023-09-24T00:00:00+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}]} \ No newline at end of file +{"version": "https://jsonfeed.org/version/1", "title": "mp-units", "home_page_url": "https://mpusz.github.io/mp-units/HEAD/", "feed_url": "https://mpusz.github.io/mp-units/HEAD/feed_json_created.json", "description": "The quantities and units library for C++", "icon": null, "authors": [{"name": "mp-units Team"}], "language": "en", "items": [{"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "title": "Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting

    \n

    The Wroc\u0142aw 2024 meeting was another efficient step in the standardization of this library.\nWe've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.\nWe've also introduced std::fixed_string to LEWG for C++26.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/25/report-from-the-wroc\u0142aw-2024-iso-c-committee-meeting.png", "date_published": "2024-11-25T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "title": "International System of Quantities (ISQ): Part 6 - Challenges", "content_html": "

    International System of Quantities (ISQ): Part 6 - Challenges

    \n

    This article might be the last one from our series. This time, we will discuss the challenges and\nissues with modeling of the ISQ in software.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges.png", "date_published": "2024-11-11T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "title": "mp-units 2.4.0 released!", "content_html": "

    mp-units 2.4.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release was unexpected. We planned a significant new feature to happen next, but while\npreparing for it, and also while writing API Reference documentation, we made so many vital fixes\nand improvements that we decided that they deserve a dedicated release first.

    \n

    This post describes the most significant improvements while a much longer list of the changes\nintroduced by the new version can be found in our Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/05/mp-units-240-released.png", "date_published": "2024-11-05T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "title": "International System of Quantities (ISQ): Part 5 - Benefits", "content_html": "

    International System of Quantities (ISQ): Part 5 - Benefits

    \n

    In the previous articles, we introduced the International System of Quantities, described how we\ncan model and implement it in a programming language, and presented the issues of software that\ndoes not use such abstraction to implement a units library.

    \n

    Some of the issues raised in Part 2 of our series\nwere addressed in Part 3 already. This article will present\nhow our ISQ model elegantly addresses the remaining problems.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits.png", "date_published": "2024-11-04T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "title": "International System of Quantities (ISQ): Part 4 - Implementing ISQ", "content_html": "

    International System of Quantities (ISQ): Part 4 - Implementing ISQ

    \n

    Up until now, we have introduced the International System of Quantities and described how we can\nmodel its main aspects. This article will present how to implement those models in a programming\nlanguage, and we will point out some of the first issues that stand in our way.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq.png", "date_published": "2024-10-28T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "title": "International System of Quantities (ISQ): Part 3 - Modeling ISQ", "content_html": "

    International System of Quantities (ISQ): Part 3 - Modeling ISQ

    \n

    The physical units libraries on the market typically only focus on modeling one or more systems\nof units. However, as we have learned, this is not the only system kind to model. Another,\nand maybe even more important, is a system of quantities. The most important example here is\nthe International System of Quantities (ISQ) defined by ISO/IEC 80000.

    \n

    This article continues our series about the International System of Quantities. This time, we will\nlearn about the main ideas behind the ISQ and describe how it can be modelled in a programming\nlanguage.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq.png", "date_published": "2024-10-21T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "title": "International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used", "content_html": "

    International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used

    \n

    This article is the next one in our series about the ISQ. After introducing the basic terms and\nsystems, this article will talk about the issues we face when we base the quantities and units\nlibrary on just units or dimensions.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used.png", "date_published": "2024-10-14T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "title": "International System of Quantities (ISQ): Part 1 - Introduction", "content_html": "

    International System of Quantities (ISQ): Part 1 - Introduction

    \n

    This post starts a series of articles about the International System of Quantities (ISQ).\nIn this series, we will describe:

    \n
      \n
    • What is ISQ?
    • \n
    • Which engineering problems does ISQ help to solve and how?
    • \n
    • How to model and implement it in the programming language?
    • \n
    • What is missing in the ISQ, and why is that a problem?
    • \n
    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction.png", "date_published": "2024-10-07T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "title": "mp-units 2.3.0 released!", "content_html": "

    mp-units 2.3.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release fine-tunes many key features of the library. This post describes the most interesting\nimprovements, while a much longer list of the changes introduced by the new version can be found in\nour Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/09/27/mp-units-230-released.png", "date_published": "2024-09-27T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "title": "Report from the St. Louis 2024 ISO C++ Committee meeting", "content_html": "

    Report from the St. Louis 2024 ISO C++ Committee meeting

    \n

    We made significant progress in the standardization of this library during the ISO C++ Committee\nmeeting in St. Louis.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting.png", "date_published": "2024-07-02T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "title": "mp-units 2.2.0 released!", "content_html": "

    mp-units 2.2.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    Among other features, this release provides long-awaited support for C++20 modules, redesigns and\nenhances text output formatting, and greatly simplifies quantity point usage. This post describes\nthose and a few other smaller interesting improvements, while a much longer list of the most\nsignificant changes introduced by the new version can be found in our\nRelease Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/06/14/mp-units-220-released.png", "date_published": "2024-06-14T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "title": "Report from the Tokyo 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Tokyo 2024 ISO C++ Committee meeting

    \n

    The Tokyo 2024 meeting was a very important step in the standardization of this library. Several\nWG21 groups reviewed proposals, and the feedback was really good.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting.png", "date_published": "2024-04-15T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "title": "mp-units 2.1.0 released!", "content_html": "

    mp-units 2.1.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe the most important of them\nin this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/12/09/mp-units-210-released.png", "date_published": "2023-12-09T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "title": "Report from the Kona 2023 ISO C++ Committee meeting", "content_html": "

    Report from the Kona 2023 ISO C++ Committee meeting

    \n

    Several groups in the ISO C++ Committee reviewed the P1935: A C++ Approach to Physical Units\nproposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potential\nstandardization of such a library and encouraged further work. The authors also got valuable\ninitial feedback that highly influenced the design of the V2 version of the mp-units library.

    \n

    In the following years, we scoped on getting more feedback from the production and design. This\nresulted in version 2 of the mp-units library that resolved many issues the users and Committee\nmembers raised. The features and interfaces of this version are close to being the best we can get\nwith the current version of the C++ language standard.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting.png", "date_published": "2023-11-12T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "title": "What's new in mp-units 2.0?", "content_html": "

    What's new in mp-units 2.0?

    \n

    After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe some of them in this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/09/24/whats-new-in-mp-units-20.png", "date_published": "2023-09-24T00:00:00+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}]} \ No newline at end of file diff --git a/HEAD/feed_json_updated.json b/HEAD/feed_json_updated.json index 1ccc14f2..b6b86afe 100644 --- a/HEAD/feed_json_updated.json +++ b/HEAD/feed_json_updated.json @@ -1 +1 @@ -{"version": "https://jsonfeed.org/version/1", "title": "mp-units", "home_page_url": "https://mpusz.github.io/mp-units/HEAD/", "feed_url": "https://mpusz.github.io/mp-units/HEAD/feed_json_updated.json", "description": "The quantities and units library for C++", "icon": null, "authors": [{"name": "mp-units Team"}], "language": "en", "items": [{"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "title": "Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting

    \n

    The Wroc\u0142aw 2024 meeting was another efficient step in the standardization of this library.\nWe've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.\nWe've also introduced std::fixed_string to LEWG for C++26.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/25/report-from-the-wroc\u0142aw-2024-iso-c-committee-meeting.png", "date_modified": "2024-11-29T12:45:06+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "title": "International System of Quantities (ISQ): Part 6 - Challenges", "content_html": "

    International System of Quantities (ISQ): Part 6 - Challenges

    \n

    This article might be the last one from our series. This time, we will discuss the challenges and\nissues with modeling of the ISQ in software.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges.png", "date_modified": "2024-11-12T08:53:31+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "title": "International System of Quantities (ISQ): Part 1 - Introduction", "content_html": "

    International System of Quantities (ISQ): Part 1 - Introduction

    \n

    This post starts a series of articles about the International System of Quantities (ISQ).\nIn this series, we will describe:

    \n
      \n
    • What is ISQ?
    • \n
    • Which engineering problems does ISQ help to solve and how?
    • \n
    • How to model and implement it in the programming language?
    • \n
    • What is missing in the ISQ, and why is that a problem?
    • \n
    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "title": "International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used", "content_html": "

    International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used

    \n

    This article is the next one in our series about the ISQ. After introducing the basic terms and\nsystems, this article will talk about the issues we face when we base the quantities and units\nlibrary on just units or dimensions.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "title": "International System of Quantities (ISQ): Part 3 - Modeling ISQ", "content_html": "

    International System of Quantities (ISQ): Part 3 - Modeling ISQ

    \n

    The physical units libraries on the market typically only focus on modeling one or more systems\nof units. However, as we have learned, this is not the only system kind to model. Another,\nand maybe even more important, is a system of quantities. The most important example here is\nthe International System of Quantities (ISQ) defined by ISO/IEC 80000.

    \n

    This article continues our series about the International System of Quantities. This time, we will\nlearn about the main ideas behind the ISQ and describe how it can be modelled in a programming\nlanguage.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "title": "International System of Quantities (ISQ): Part 4 - Implementing ISQ", "content_html": "

    International System of Quantities (ISQ): Part 4 - Implementing ISQ

    \n

    Up until now, we have introduced the International System of Quantities and described how we can\nmodel its main aspects. This article will present how to implement those models in a programming\nlanguage, and we will point out some of the first issues that stand in our way.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "title": "International System of Quantities (ISQ): Part 5 - Benefits", "content_html": "

    International System of Quantities (ISQ): Part 5 - Benefits

    \n

    In the previous articles, we introduced the International System of Quantities, described how we\ncan model and implement it in a programming language, and presented the issues of software that\ndoes not use such abstraction to implement a units library.

    \n

    Some of the issues raised in Part 2 of our series\nwere addressed in Part 3 already. This article will present\nhow our ISQ model elegantly addresses the remaining problems.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "mpusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "title": "mp-units 2.4.0 released!", "content_html": "

    mp-units 2.4.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release was unexpected. We planned a significant new feature to happen next, but while\npreparing for it, and also while writing API Reference documentation, we made so many vital fixes\nand improvements that we decided that they deserve a dedicated release first.

    \n

    This post describes the most significant improvements while a much longer list of the changes\nintroduced by the new version can be found in our Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/05/mp-units-240-released.png", "date_modified": "2024-11-05T18:46:13+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "title": "mp-units 2.3.0 released!", "content_html": "

    mp-units 2.3.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release fine-tunes many key features of the library. This post describes the most interesting\nimprovements, while a much longer list of the changes introduced by the new version can be found in\nour Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/09/27/mp-units-230-released.png", "date_modified": "2024-09-30T17:11:10+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "title": "What's new in mp-units 2.0?", "content_html": "

    What's new in mp-units 2.0?

    \n

    After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe some of them in this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/09/24/whats-new-in-mp-units-20.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "title": "mp-units 2.1.0 released!", "content_html": "

    mp-units 2.1.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe the most important of them\nin this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/12/09/mp-units-210-released.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "title": "mp-units 2.2.0 released!", "content_html": "

    mp-units 2.2.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    Among other features, this release provides long-awaited support for C++20 modules, redesigns and\nenhances text output formatting, and greatly simplifies quantity point usage. This post describes\nthose and a few other smaller interesting improvements, while a much longer list of the most\nsignificant changes introduced by the new version can be found in our\nRelease Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/06/14/mp-units-220-released.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "mpusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "title": "Report from the Kona 2023 ISO C++ Committee meeting", "content_html": "

    Report from the Kona 2023 ISO C++ Committee meeting

    \n

    Several groups in the ISO C++ Committee reviewed the P1935: A C++ Approach to Physical Units\nproposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potential\nstandardization of such a library and encouraged further work. The authors also got valuable\ninitial feedback that highly influenced the design of the V2 version of the mp-units library.

    \n

    In the following years, we scoped on getting more feedback from the production and design. This\nresulted in version 2 of the mp-units library that resolved many issues the users and Committee\nmembers raised. The features and interfaces of this version are close to being the best we can get\nwith the current version of the C++ language standard.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "title": "Report from the St. Louis 2024 ISO C++ Committee meeting", "content_html": "

    Report from the St. Louis 2024 ISO C++ Committee meeting

    \n

    We made significant progress in the standardization of this library during the ISO C++ Committee\nmeeting in St. Louis.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "title": "Report from the Tokyo 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Tokyo 2024 ISO C++ Committee meeting

    \n

    The Tokyo 2024 meeting was a very important step in the standardization of this library. Several\nWG21 groups reviewed proposals, and the feedback was really good.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "mpusz"}], "tags": ["WG21 Updates"]}]} \ No newline at end of file +{"version": "https://jsonfeed.org/version/1", "title": "mp-units", "home_page_url": "https://mpusz.github.io/mp-units/HEAD/", "feed_url": "https://mpusz.github.io/mp-units/HEAD/feed_json_updated.json", "description": "The quantities and units library for C++", "icon": null, "authors": [{"name": "mp-units Team"}], "language": "en", "items": [{"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/", "title": "Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Wroc\u0142aw 2024 ISO C++ Committee meeting

    \n

    The Wroc\u0142aw 2024 meeting was another efficient step in the standardization of this library.\nWe've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.\nWe've also introduced std::fixed_string to LEWG for C++26.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/25/report-from-the-wroc\u0142aw-2024-iso-c-committee-meeting.png", "date_modified": "2024-11-29T12:45:06+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/", "title": "International System of Quantities (ISQ): Part 6 - Challenges", "content_html": "

    International System of Quantities (ISQ): Part 6 - Challenges

    \n

    This article might be the last one from our series. This time, we will discuss the challenges and\nissues with modeling of the ISQ in software.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges.png", "date_modified": "2024-11-12T08:53:31+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/", "title": "International System of Quantities (ISQ): Part 1 - Introduction", "content_html": "

    International System of Quantities (ISQ): Part 1 - Introduction

    \n

    This post starts a series of articles about the International System of Quantities (ISQ).\nIn this series, we will describe:

    \n
      \n
    • What is ISQ?
    • \n
    • Which engineering problems does ISQ help to solve and how?
    • \n
    • How to model and implement it in the programming language?
    • \n
    • What is missing in the ISQ, and why is that a problem?
    • \n
    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/", "title": "International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used", "content_html": "

    International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used

    \n

    This article is the next one in our series about the ISQ. After introducing the basic terms and\nsystems, this article will talk about the issues we face when we base the quantities and units\nlibrary on just units or dimensions.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/", "title": "International System of Quantities (ISQ): Part 3 - Modeling ISQ", "content_html": "

    International System of Quantities (ISQ): Part 3 - Modeling ISQ

    \n

    The physical units libraries on the market typically only focus on modeling one or more systems\nof units. However, as we have learned, this is not the only system kind to model. Another,\nand maybe even more important, is a system of quantities. The most important example here is\nthe International System of Quantities (ISQ) defined by ISO/IEC 80000.

    \n

    This article continues our series about the International System of Quantities. This time, we will\nlearn about the main ideas behind the ISQ and describe how it can be modelled in a programming\nlanguage.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/", "title": "International System of Quantities (ISQ): Part 4 - Implementing ISQ", "content_html": "

    International System of Quantities (ISQ): Part 4 - Implementing ISQ

    \n

    Up until now, we have introduced the International System of Quantities and described how we can\nmodel its main aspects. This article will present how to implement those models in a programming\nlanguage, and we will point out some of the first issues that stand in our way.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/", "title": "International System of Quantities (ISQ): Part 5 - Benefits", "content_html": "

    International System of Quantities (ISQ): Part 5 - Benefits

    \n

    In the previous articles, we introduced the International System of Quantities, described how we\ncan model and implement it in a programming language, and presented the issues of software that\ndoes not use such abstraction to implement a units library.

    \n

    Some of the issues raised in Part 2 of our series\nwere addressed in Part 3 already. This article will present\nhow our ISQ model elegantly addresses the remaining problems.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits.png", "date_modified": "2024-11-11T22:37:29+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Metrology"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/", "title": "mp-units 2.4.0 released!", "content_html": "

    mp-units 2.4.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release was unexpected. We planned a significant new feature to happen next, but while\npreparing for it, and also while writing API Reference documentation, we made so many vital fixes\nand improvements that we decided that they deserve a dedicated release first.

    \n

    This post describes the most significant improvements while a much longer list of the changes\nintroduced by the new version can be found in our Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/11/05/mp-units-240-released.png", "date_modified": "2024-11-05T18:46:13+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/", "title": "mp-units 2.3.0 released!", "content_html": "

    mp-units 2.3.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    This release fine-tunes many key features of the library. This post describes the most interesting\nimprovements, while a much longer list of the changes introduced by the new version can be found in\nour Release Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/09/27/mp-units-230-released.png", "date_modified": "2024-09-30T17:11:10+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/", "title": "What's new in mp-units 2.0?", "content_html": "

    What's new in mp-units 2.0?

    \n

    After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe some of them in this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/09/24/whats-new-in-mp-units-20.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/", "title": "mp-units 2.1.0 released!", "content_html": "

    mp-units 2.1.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    The list of the most significant changes introduced by the new version can be found in our\nRelease Notes. We will also describe the most important of them\nin this post.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/12/09/mp-units-210-released.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/", "title": "mp-units 2.2.0 released!", "content_html": "

    mp-units 2.2.0 released!

    \n

    A new product version can be obtained from\nGitHub and\nConan.

    \n

    Among other features, this release provides long-awaited support for C++20 modules, redesigns and\nenhances text output formatting, and greatly simplifies quantity point usage. This post describes\nthose and a few other smaller interesting improvements, while a much longer list of the most\nsignificant changes introduced by the new version can be found in our\nRelease Notes.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/06/14/mp-units-220-released.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["Releases"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/", "title": "Report from the Kona 2023 ISO C++ Committee meeting", "content_html": "

    Report from the Kona 2023 ISO C++ Committee meeting

    \n

    Several groups in the ISO C++ Committee reviewed the P1935: A C++ Approach to Physical Units\nproposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potential\nstandardization of such a library and encouraged further work. The authors also got valuable\ninitial feedback that highly influenced the design of the V2 version of the mp-units library.

    \n

    In the following years, we scoped on getting more feedback from the production and design. This\nresulted in version 2 of the mp-units library that resolved many issues the users and Committee\nmembers raised. The features and interfaces of this version are close to being the best we can get\nwith the current version of the C++ language standard.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/", "title": "Report from the St. Louis 2024 ISO C++ Committee meeting", "content_html": "

    Report from the St. Louis 2024 ISO C++ Committee meeting

    \n

    We made significant progress in the standardization of this library during the ISO C++ Committee\nmeeting in St. Louis.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}, {"id": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "url": "https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/", "title": "Report from the Tokyo 2024 ISO C++ Committee meeting", "content_html": "

    Report from the Tokyo 2024 ISO C++ Committee meeting

    \n

    The Tokyo 2024 meeting was a very important step in the standardization of this library. Several\nWG21 groups reviewed proposals, and the feedback was really good.

    ", "image": "https://mpusz.github.io/mp-units/HEADassets/images/social/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting.png", "date_modified": "2024-09-30T12:47:28+00:00", "authors": [{"name": "Mateusz Pusz"}], "tags": ["WG21 Updates"]}]} \ No newline at end of file diff --git a/HEAD/feed_rss_created.xml b/HEAD/feed_rss_created.xml index ccf107a3..a25e2f90 100644 --- a/HEAD/feed_rss_created.xml +++ b/HEAD/feed_rss_created.xml @@ -1 +1 @@ - mp-unitsThe quantities and units library for C++https://mpusz.github.io/mp-units/HEAD/mp-units Teamhttps://github.com/mpusz/mp-unitsen Sun, 01 Dec 2024 12:44:34 -0000 Sun, 01 Dec 2024 12:44:34 -0000 1440 MkDocs RSS plugin - v1.16.0 Report from the Wrocław 2024 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the Wrocław 2024 ISO C++ Committee meeting</h1><p>The Wrocław 2024 meeting was another efficient step in the standardization of this library.We've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.We've also introduced <code>std::fixed_string</code> to LEWG for C++26.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ Mon, 25 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ International System of Quantities (ISQ): Part 6 - Challenges mpusz Metrology <h1>International System of Quantities (ISQ): Part 6 - Challenges</h1><p>This article might be the last one from our series. This time, we will discuss the challenges andissues with modeling of the ISQ in software.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ Mon, 11 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ mp-units 2.4.0 released! mpusz Releases <h1>mp-units 2.4.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.4.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.4.0">Conan</a>.</strong></p><p>This release was unexpected. We planned a significant new feature to happen next, but whilepreparing for it, and also while writing API Reference documentation, we made so many vital fixesand improvements that we decided that they deserve a dedicated release first.</p><p>This post describes the most significant improvements while a much longer list of the changesintroduced by the new version can be found in our <a href="../../release_notes.md#2.4.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ Tue, 05 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ International System of Quantities (ISQ): Part 5 - Benefits mpusz Metrology <h1>International System of Quantities (ISQ): Part 5 - Benefits</h1><p>In the previous articles, we introduced the International System of Quantities, described how wecan model and implement it in a programming language, and presented the issues of software thatdoes not use such abstraction to implement a units library.</p><p>Some of the issues raised in <a href="isq-part-2-problems-when-isq-is-not-used.md">Part 2</a> of our serieswere addressed in <a href="isq-part-3-modeling-isq.md">Part 3</a> already. This article will presenthow our ISQ model elegantly addresses the remaining problems.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ Mon, 04 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ International System of Quantities (ISQ): Part 4 - Implementing ISQ mpusz Metrology <h1>International System of Quantities (ISQ): Part 4 - Implementing ISQ</h1><p>Up until now, we have introduced the International System of Quantities and described how we canmodel its main aspects. This article will present how to implement those models in a programminglanguage, and we will point out some of the first issues that stand in our way.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ Mon, 28 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ International System of Quantities (ISQ): Part 3 - Modeling ISQ mpusz Metrology <h1>International System of Quantities (ISQ): Part 3 - Modeling ISQ</h1><p>The physical units libraries on the market typically only focus on modeling one or more systemsof units. However, as we have learned, this is not the only system kind to model. Another,and maybe even more important, is a system of quantities. The most important example here isthe International System of Quantities (ISQ) defined by ISO/IEC 80000.</p><p>This article continues our series about the International System of Quantities. This time, we willlearn about the main ideas behind the ISQ and describe how it can be modelled in a programminglanguage.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ Mon, 21 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used mpusz Metrology <h1>International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used</h1><p>This article is the next one in our series about the ISQ. After introducing the basic terms andsystems, this article will talk about the issues we face when we base the quantities and unitslibrary on just units or dimensions.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ Mon, 14 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ International System of Quantities (ISQ): Part 1 - Introduction mpusz Metrology <h1>International System of Quantities (ISQ): Part 1 - Introduction</h1><p>This post starts a series of articles about the International System of Quantities (ISQ).In this series, we will describe:</p><ul><li>What is ISQ?</li><li>Which engineering problems does ISQ help to solve and how?</li><li>How to model and implement it in the programming language?</li><li>What is missing in the ISQ, and why is that a problem?</li></ul>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ Mon, 07 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ mp-units 2.3.0 released! mpusz Releases <h1>mp-units 2.3.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.3.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.3.0">Conan</a>.</strong></p><p>This release fine-tunes many key features of the library. This post describes the most interestingimprovements, while a much longer list of the changes introduced by the new version can be found inour <a href="../../release_notes.md#2.3.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ Fri, 27 Sep 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ Report from the St. Louis 2024 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the St. Louis 2024 ISO C++ Committee meeting</h1><p>We made significant progress in the standardization of this library during the ISO C++ Committeemeeting in St. Louis.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ Tue, 02 Jul 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ mp-units 2.2.0 released! mpusz Releases <h1>mp-units 2.2.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.2.1">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.2.1">Conan</a>.</strong></p><p>Among other features, this release provides long-awaited support for C++20 modules, redesigns andenhances text output formatting, and greatly simplifies quantity point usage. This post describesthose and a few other smaller interesting improvements, while a much longer list of the mostsignificant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.2.1">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Fri, 14 Jun 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Report from the Tokyo 2024 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the Tokyo 2024 ISO C++ Committee meeting</h1><p>The Tokyo 2024 meeting was a very important step in the standardization of this library. SeveralWG21 groups reviewed proposals, and the feedback was really good.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ Mon, 15 Apr 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ mp-units 2.1.0 released! mpusz Releases <h1>mp-units 2.1.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.1.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.1.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.1.0">Release Notes</a>. We will also describe the most important of themin this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ Sat, 09 Dec 2023 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ Report from the Kona 2023 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the Kona 2023 ISO C++ Committee meeting</h1><p><strong>Several groups in the ISO C++ Committee reviewed the <a href="https://wg21.link/p1935">P1935: A C++ Approach to Physical Units</a>proposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potentialstandardization of such a library and encouraged further work. The authors also got valuableinitial feedback that highly influenced the design of the V2 version of the mp-units library.</strong></p><p>In the following years, we scoped on getting more feedback from the production and design. Thisresulted in version 2 of the <strong>mp-units</strong> library that resolved many issues the users and Committeemembers raised. The features and interfaces of this version are close to being the best we can getwith the current version of the C++ language standard.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ Sun, 12 Nov 2023 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ What's new in mp-units 2.0? mpusz Releases <h1>What's new in mp-units 2.0?</h1><p><strong>After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.0.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.0.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.0.0">Release Notes</a>. We will also describe some of them in this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ Sun, 24 Sep 2023 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ \ No newline at end of file + mp-unitsThe quantities and units library for C++https://mpusz.github.io/mp-units/HEAD/mp-units Teamhttps://github.com/mpusz/mp-unitsen Sun, 08 Dec 2024 08:57:06 -0000 Sun, 08 Dec 2024 08:57:06 -0000 1440 MkDocs RSS plugin - v1.17.0 None mp-unitshttps://mpusz.github.io/mp-units/HEAD/ Report from the Wrocław 2024 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the Wrocław 2024 ISO C++ Committee meeting</h1><p>The Wrocław 2024 meeting was another efficient step in the standardization of this library.We've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.We've also introduced <code>std::fixed_string</code> to LEWG for C++26.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ Mon, 25 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ International System of Quantities (ISQ): Part 6 - Challenges Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 6 - Challenges</h1><p>This article might be the last one from our series. This time, we will discuss the challenges andissues with modeling of the ISQ in software.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ Mon, 11 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ mp-units 2.4.0 released! Mateusz Pusz Releases <h1>mp-units 2.4.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.4.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.4.0">Conan</a>.</strong></p><p>This release was unexpected. We planned a significant new feature to happen next, but whilepreparing for it, and also while writing API Reference documentation, we made so many vital fixesand improvements that we decided that they deserve a dedicated release first.</p><p>This post describes the most significant improvements while a much longer list of the changesintroduced by the new version can be found in our <a href="../../release_notes.md#2.4.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ Tue, 05 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ International System of Quantities (ISQ): Part 5 - Benefits Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 5 - Benefits</h1><p>In the previous articles, we introduced the International System of Quantities, described how wecan model and implement it in a programming language, and presented the issues of software thatdoes not use such abstraction to implement a units library.</p><p>Some of the issues raised in <a href="isq-part-2-problems-when-isq-is-not-used.md">Part 2</a> of our serieswere addressed in <a href="isq-part-3-modeling-isq.md">Part 3</a> already. This article will presenthow our ISQ model elegantly addresses the remaining problems.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ Mon, 04 Nov 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ International System of Quantities (ISQ): Part 4 - Implementing ISQ Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 4 - Implementing ISQ</h1><p>Up until now, we have introduced the International System of Quantities and described how we canmodel its main aspects. This article will present how to implement those models in a programminglanguage, and we will point out some of the first issues that stand in our way.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ Mon, 28 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ International System of Quantities (ISQ): Part 3 - Modeling ISQ Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 3 - Modeling ISQ</h1><p>The physical units libraries on the market typically only focus on modeling one or more systemsof units. However, as we have learned, this is not the only system kind to model. Another,and maybe even more important, is a system of quantities. The most important example here isthe International System of Quantities (ISQ) defined by ISO/IEC 80000.</p><p>This article continues our series about the International System of Quantities. This time, we willlearn about the main ideas behind the ISQ and describe how it can be modelled in a programminglanguage.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ Mon, 21 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used</h1><p>This article is the next one in our series about the ISQ. After introducing the basic terms andsystems, this article will talk about the issues we face when we base the quantities and unitslibrary on just units or dimensions.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ Mon, 14 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ International System of Quantities (ISQ): Part 1 - Introduction Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 1 - Introduction</h1><p>This post starts a series of articles about the International System of Quantities (ISQ).In this series, we will describe:</p><ul><li>What is ISQ?</li><li>Which engineering problems does ISQ help to solve and how?</li><li>How to model and implement it in the programming language?</li><li>What is missing in the ISQ, and why is that a problem?</li></ul>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ Mon, 07 Oct 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ mp-units 2.3.0 released! Mateusz Pusz Releases <h1>mp-units 2.3.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.3.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.3.0">Conan</a>.</strong></p><p>This release fine-tunes many key features of the library. This post describes the most interestingimprovements, while a much longer list of the changes introduced by the new version can be found inour <a href="../../release_notes.md#2.3.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ Fri, 27 Sep 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ Report from the St. Louis 2024 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the St. Louis 2024 ISO C++ Committee meeting</h1><p>We made significant progress in the standardization of this library during the ISO C++ Committeemeeting in St. Louis.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ Tue, 02 Jul 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ mp-units 2.2.0 released! Mateusz Pusz Releases <h1>mp-units 2.2.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.2.1">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.2.1">Conan</a>.</strong></p><p>Among other features, this release provides long-awaited support for C++20 modules, redesigns andenhances text output formatting, and greatly simplifies quantity point usage. This post describesthose and a few other smaller interesting improvements, while a much longer list of the mostsignificant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.2.1">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Fri, 14 Jun 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Report from the Tokyo 2024 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the Tokyo 2024 ISO C++ Committee meeting</h1><p>The Tokyo 2024 meeting was a very important step in the standardization of this library. SeveralWG21 groups reviewed proposals, and the feedback was really good.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ Mon, 15 Apr 2024 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ mp-units 2.1.0 released! Mateusz Pusz Releases <h1>mp-units 2.1.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.1.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.1.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.1.0">Release Notes</a>. We will also describe the most important of themin this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ Sat, 09 Dec 2023 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ Report from the Kona 2023 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the Kona 2023 ISO C++ Committee meeting</h1><p><strong>Several groups in the ISO C++ Committee reviewed the <a href="https://wg21.link/p1935">P1935: A C++ Approach to Physical Units</a>proposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potentialstandardization of such a library and encouraged further work. The authors also got valuableinitial feedback that highly influenced the design of the V2 version of the mp-units library.</strong></p><p>In the following years, we scoped on getting more feedback from the production and design. Thisresulted in version 2 of the <strong>mp-units</strong> library that resolved many issues the users and Committeemembers raised. The features and interfaces of this version are close to being the best we can getwith the current version of the C++ language standard.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ Sun, 12 Nov 2023 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ What's new in mp-units 2.0? Mateusz Pusz Releases <h1>What's new in mp-units 2.0?</h1><p><strong>After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.0.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.0.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.0.0">Release Notes</a>. We will also describe some of them in this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ Sun, 24 Sep 2023 00:00:00 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ \ No newline at end of file diff --git a/HEAD/feed_rss_updated.xml b/HEAD/feed_rss_updated.xml index ffc8be9b..3e1266a7 100644 --- a/HEAD/feed_rss_updated.xml +++ b/HEAD/feed_rss_updated.xml @@ -1 +1 @@ - mp-unitsThe quantities and units library for C++https://mpusz.github.io/mp-units/HEAD/mp-units Teamhttps://github.com/mpusz/mp-unitsen Sun, 01 Dec 2024 12:44:34 -0000 Sun, 01 Dec 2024 12:44:34 -0000 1440 MkDocs RSS plugin - v1.16.0 Report from the Wrocław 2024 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the Wrocław 2024 ISO C++ Committee meeting</h1><p>The Wrocław 2024 meeting was another efficient step in the standardization of this library.We've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.We've also introduced <code>std::fixed_string</code> to LEWG for C++26.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ Fri, 29 Nov 2024 12:45:06 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ International System of Quantities (ISQ): Part 6 - Challenges mpusz Metrology <h1>International System of Quantities (ISQ): Part 6 - Challenges</h1><p>This article might be the last one from our series. This time, we will discuss the challenges andissues with modeling of the ISQ in software.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ Tue, 12 Nov 2024 08:53:31 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ International System of Quantities (ISQ): Part 1 - Introduction mpusz Metrology <h1>International System of Quantities (ISQ): Part 1 - Introduction</h1><p>This post starts a series of articles about the International System of Quantities (ISQ).In this series, we will describe:</p><ul><li>What is ISQ?</li><li>Which engineering problems does ISQ help to solve and how?</li><li>How to model and implement it in the programming language?</li><li>What is missing in the ISQ, and why is that a problem?</li></ul>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used mpusz Metrology <h1>International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used</h1><p>This article is the next one in our series about the ISQ. After introducing the basic terms andsystems, this article will talk about the issues we face when we base the quantities and unitslibrary on just units or dimensions.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ International System of Quantities (ISQ): Part 3 - Modeling ISQ mpusz Metrology <h1>International System of Quantities (ISQ): Part 3 - Modeling ISQ</h1><p>The physical units libraries on the market typically only focus on modeling one or more systemsof units. However, as we have learned, this is not the only system kind to model. Another,and maybe even more important, is a system of quantities. The most important example here isthe International System of Quantities (ISQ) defined by ISO/IEC 80000.</p><p>This article continues our series about the International System of Quantities. This time, we willlearn about the main ideas behind the ISQ and describe how it can be modelled in a programminglanguage.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ International System of Quantities (ISQ): Part 4 - Implementing ISQ mpusz Metrology <h1>International System of Quantities (ISQ): Part 4 - Implementing ISQ</h1><p>Up until now, we have introduced the International System of Quantities and described how we canmodel its main aspects. This article will present how to implement those models in a programminglanguage, and we will point out some of the first issues that stand in our way.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ International System of Quantities (ISQ): Part 5 - Benefits mpusz Metrology <h1>International System of Quantities (ISQ): Part 5 - Benefits</h1><p>In the previous articles, we introduced the International System of Quantities, described how wecan model and implement it in a programming language, and presented the issues of software thatdoes not use such abstraction to implement a units library.</p><p>Some of the issues raised in <a href="isq-part-2-problems-when-isq-is-not-used.md">Part 2</a> of our serieswere addressed in <a href="isq-part-3-modeling-isq.md">Part 3</a> already. This article will presenthow our ISQ model elegantly addresses the remaining problems.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ mp-units 2.4.0 released! mpusz Releases <h1>mp-units 2.4.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.4.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.4.0">Conan</a>.</strong></p><p>This release was unexpected. We planned a significant new feature to happen next, but whilepreparing for it, and also while writing API Reference documentation, we made so many vital fixesand improvements that we decided that they deserve a dedicated release first.</p><p>This post describes the most significant improvements while a much longer list of the changesintroduced by the new version can be found in our <a href="../../release_notes.md#2.4.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ Tue, 05 Nov 2024 18:46:13 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ mp-units 2.3.0 released! mpusz Releases <h1>mp-units 2.3.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.3.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.3.0">Conan</a>.</strong></p><p>This release fine-tunes many key features of the library. This post describes the most interestingimprovements, while a much longer list of the changes introduced by the new version can be found inour <a href="../../release_notes.md#2.3.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ Mon, 30 Sep 2024 17:11:10 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ What's new in mp-units 2.0? mpusz Releases <h1>What's new in mp-units 2.0?</h1><p><strong>After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.0.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.0.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.0.0">Release Notes</a>. We will also describe some of them in this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ mp-units 2.1.0 released! mpusz Releases <h1>mp-units 2.1.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.1.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.1.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.1.0">Release Notes</a>. We will also describe the most important of themin this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ mp-units 2.2.0 released! mpusz Releases <h1>mp-units 2.2.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.2.1">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.2.1">Conan</a>.</strong></p><p>Among other features, this release provides long-awaited support for C++20 modules, redesigns andenhances text output formatting, and greatly simplifies quantity point usage. This post describesthose and a few other smaller interesting improvements, while a much longer list of the mostsignificant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.2.1">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Report from the Kona 2023 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the Kona 2023 ISO C++ Committee meeting</h1><p><strong>Several groups in the ISO C++ Committee reviewed the <a href="https://wg21.link/p1935">P1935: A C++ Approach to Physical Units</a>proposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potentialstandardization of such a library and encouraged further work. The authors also got valuableinitial feedback that highly influenced the design of the V2 version of the mp-units library.</strong></p><p>In the following years, we scoped on getting more feedback from the production and design. Thisresulted in version 2 of the <strong>mp-units</strong> library that resolved many issues the users and Committeemembers raised. The features and interfaces of this version are close to being the best we can getwith the current version of the C++ language standard.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ Report from the St. Louis 2024 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the St. Louis 2024 ISO C++ Committee meeting</h1><p>We made significant progress in the standardization of this library during the ISO C++ Committeemeeting in St. Louis.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ Report from the Tokyo 2024 ISO C++ Committee meeting mpusz WG21 Updates <h1>Report from the Tokyo 2024 ISO C++ Committee meeting</h1><p>The Tokyo 2024 meeting was a very important step in the standardization of this library. SeveralWG21 groups reviewed proposals, and the feedback was really good.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ \ No newline at end of file + mp-unitsThe quantities and units library for C++https://mpusz.github.io/mp-units/HEAD/mp-units Teamhttps://github.com/mpusz/mp-unitsen Sun, 08 Dec 2024 08:57:06 -0000 Sun, 08 Dec 2024 08:57:06 -0000 1440 MkDocs RSS plugin - v1.17.0 None mp-unitshttps://mpusz.github.io/mp-units/HEAD/ Report from the Wrocław 2024 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the Wrocław 2024 ISO C++ Committee meeting</h1><p>The Wrocław 2024 meeting was another efficient step in the standardization of this library.We've spent the entire day on the joint LEWGI and SG6 discussion and got lots of feedback.We've also introduced <code>std::fixed_string</code> to LEWG for C++26.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ Fri, 29 Nov 2024 12:45:06 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ International System of Quantities (ISQ): Part 6 - Challenges Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 6 - Challenges</h1><p>This article might be the last one from our series. This time, we will discuss the challenges andissues with modeling of the ISQ in software.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ Tue, 12 Nov 2024 08:53:31 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ International System of Quantities (ISQ): Part 1 - Introduction Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 1 - Introduction</h1><p>This post starts a series of articles about the International System of Quantities (ISQ).In this series, we will describe:</p><ul><li>What is ISQ?</li><li>Which engineering problems does ISQ help to solve and how?</li><li>How to model and implement it in the programming language?</li><li>What is missing in the ISQ, and why is that a problem?</li></ul>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 2 - Problems when ISQ is not used</h1><p>This article is the next one in our series about the ISQ. After introducing the basic terms andsystems, this article will talk about the issues we face when we base the quantities and unitslibrary on just units or dimensions.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ International System of Quantities (ISQ): Part 3 - Modeling ISQ Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 3 - Modeling ISQ</h1><p>The physical units libraries on the market typically only focus on modeling one or more systemsof units. However, as we have learned, this is not the only system kind to model. Another,and maybe even more important, is a system of quantities. The most important example here isthe International System of Quantities (ISQ) defined by ISO/IEC 80000.</p><p>This article continues our series about the International System of Quantities. This time, we willlearn about the main ideas behind the ISQ and describe how it can be modelled in a programminglanguage.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ International System of Quantities (ISQ): Part 4 - Implementing ISQ Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 4 - Implementing ISQ</h1><p>Up until now, we have introduced the International System of Quantities and described how we canmodel its main aspects. This article will present how to implement those models in a programminglanguage, and we will point out some of the first issues that stand in our way.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ International System of Quantities (ISQ): Part 5 - Benefits Mateusz Pusz Metrology <h1>International System of Quantities (ISQ): Part 5 - Benefits</h1><p>In the previous articles, we introduced the International System of Quantities, described how wecan model and implement it in a programming language, and presented the issues of software thatdoes not use such abstraction to implement a units library.</p><p>Some of the issues raised in <a href="isq-part-2-problems-when-isq-is-not-used.md">Part 2</a> of our serieswere addressed in <a href="isq-part-3-modeling-isq.md">Part 3</a> already. This article will presenthow our ISQ model elegantly addresses the remaining problems.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ Mon, 11 Nov 2024 22:37:29 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ mp-units 2.4.0 released! Mateusz Pusz Releases <h1>mp-units 2.4.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.4.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.4.0">Conan</a>.</strong></p><p>This release was unexpected. We planned a significant new feature to happen next, but whilepreparing for it, and also while writing API Reference documentation, we made so many vital fixesand improvements that we decided that they deserve a dedicated release first.</p><p>This post describes the most significant improvements while a much longer list of the changesintroduced by the new version can be found in our <a href="../../release_notes.md#2.4.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ Tue, 05 Nov 2024 18:46:13 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ mp-units 2.3.0 released! Mateusz Pusz Releases <h1>mp-units 2.3.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.3.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.3.0">Conan</a>.</strong></p><p>This release fine-tunes many key features of the library. This post describes the most interestingimprovements, while a much longer list of the changes introduced by the new version can be found inour <a href="../../release_notes.md#2.3.0">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ Mon, 30 Sep 2024 17:11:10 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ What's new in mp-units 2.0? Mateusz Pusz Releases <h1>What's new in mp-units 2.0?</h1><p><strong>After a year of hard work, we've just released mp-units 2.0.0. It can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.0.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.0.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.0.0">Release Notes</a>. We will also describe some of them in this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ mp-units 2.1.0 released! Mateusz Pusz Releases <h1>mp-units 2.1.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.1.0">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.1.0">Conan</a>.</strong></p><p>The list of the most significant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.1.0">Release Notes</a>. We will also describe the most important of themin this post.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ mp-units 2.2.0 released! Mateusz Pusz Releases <h1>mp-units 2.2.0 released!</h1><p><strong>A new product version can be obtained from<a href="https://github.com/mpusz/mp-units/releases/tag/v2.2.1">GitHub</a> and<a href="https://conan.io/center/recipes/mp-units?version=2.2.1">Conan</a>.</strong></p><p>Among other features, this release provides long-awaited support for C++20 modules, redesigns andenhances text output formatting, and greatly simplifies quantity point usage. This post describesthose and a few other smaller interesting improvements, while a much longer list of the mostsignificant changes introduced by the new version can be found in our<a href="../../release_notes.md#2.2.1">Release Notes</a>.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ Report from the Kona 2023 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the Kona 2023 ISO C++ Committee meeting</h1><p><strong>Several groups in the ISO C++ Committee reviewed the <a href="https://wg21.link/p1935">P1935: A C++ Approach to Physical Units</a>proposal in Belfast 2019 and Prague 2020. All those groups expressed interest in the potentialstandardization of such a library and encouraged further work. The authors also got valuableinitial feedback that highly influenced the design of the V2 version of the mp-units library.</strong></p><p>In the following years, we scoped on getting more feedback from the production and design. Thisresulted in version 2 of the <strong>mp-units</strong> library that resolved many issues the users and Committeemembers raised. The features and interfaces of this version are close to being the best we can getwith the current version of the C++ language standard.</p>https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ Report from the St. Louis 2024 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the St. Louis 2024 ISO C++ Committee meeting</h1><p>We made significant progress in the standardization of this library during the ISO C++ Committeemeeting in St. Louis.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ Report from the Tokyo 2024 ISO C++ Committee meeting Mateusz Pusz WG21 Updates <h1>Report from the Tokyo 2024 ISO C++ Committee meeting</h1><p>The Tokyo 2024 meeting was a very important step in the standardization of this library. SeveralWG21 groups reviewed proposals, and the feedback was really good.</p>https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ Mon, 30 Sep 2024 12:47:28 +0000mp-unitshttps://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ \ No newline at end of file diff --git a/HEAD/sitemap.xml b/HEAD/sitemap.xml index 987f268c..97d23956 100644 --- a/HEAD/sitemap.xml +++ b/HEAD/sitemap.xml @@ -2,274 +2,274 @@ https://mpusz.github.io/mp-units/HEAD/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/api_reference/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/release_notes/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/appendix/glossary/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/appendix/references/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2023/09/24/whats-new-in-mp-units-20/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2023/12/09/mp-units-210-released/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/06/14/mp-units-220-released/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/09/27/mp-units-230-released/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/11/05/mp-units-240-released/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/10/07/international-system-of-quantities-isq-part-1---introduction/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/10/14/international-system-of-quantities-isq-part-2---problems-when-isq-is-not-used/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/10/21/international-system-of-quantities-isq-part-3---modeling-isq/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/10/28/international-system-of-quantities-isq-part-4---implementing-isq/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/11/04/international-system-of-quantities-isq-part-5---benefits/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/11/11/international-system-of-quantities-isq-part-6---challenges/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2023/11/12/report-from-the-kona-2023-iso-c-committee-meeting/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/07/02/report-from-the-st-louis-2024-iso-c-committee-meeting/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/04/15/report-from-the-tokyo-2024-iso-c-committee-meeting/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/2024/11/25/report-from-the-wroc%C5%82aw-2024-iso-c-committee-meeting/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/contributing/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/cpp_compiler_support/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/faq/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/installation_and_usage/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/introduction/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/look_and_feel/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/project_structure/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/getting_started/quick_start/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/terms_and_definitions/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/examples/avg_speed/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/examples/hello_units/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/examples/hw_voltage/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/examples/si_constants/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/character_of_a_quantity/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/concepts/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/design_overview/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/dimensionless_quantities/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/faster_than_lightspeed_constants/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/generic_interfaces/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/interface_introduction/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/obtaining_metadata/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/quantity_arithmetics/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/simple_and_typed_quantities/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/systems_of_quantities/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/systems_of_units/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/text_output/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/the_affine_space/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/framework_basics/value_conversions/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/systems/introduction/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/systems/isq/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/systems/natural_units/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/systems/si/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/systems/strong_angular_system/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/use_cases/extending_the_library/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/use_cases/interoperability_with_other_libraries/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/use_cases/pure_dimensional_analysis/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/use_cases/using_custom_representation_types/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/use_cases/wide_compatibility/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/use_cases/working_with_legacy_interfaces/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/archive/2024/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/archive/2023/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/category/wg21-updates/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/category/metrology/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/category/releases/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/page/2/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/blog/archive/2024/page/2/ - 2024-12-01 + 2024-12-08 https://mpusz.github.io/mp-units/HEAD/users_guide/examples/tags_index/ - 2024-12-01 + 2024-12-08 \ No newline at end of file diff --git a/HEAD/sitemap.xml.gz b/HEAD/sitemap.xml.gz index 91a98510d8a2b2911a544b97e2d54789d5dc0912..95119d48d70298f4c7692618a647afa74f7edb31 100644 GIT binary patch delta 999 zcmX@fagu{wzMF%i;bF)`b{)1TDeoMONfRyQtZsGNx|rO%yY^M-)?EzOf1TU$FYoL1 z`TM(PU)}!Of4gN=ONnEz?7g*ZQx5qD`CZ=PHaX!6<8`}lLbn?yP86=cw*C84O^<#_ z=VSHP_If(sTi3gM(}{B`Q|kYG`@H^B*tBiy^RLcuyMNa_bhBWo@+#@9qE*)4RL{@- zTe00rLNt+m;uc14N0$u?1gCuFEU@%tDVSS1Y46t#D>*TC%l^|zRyU*W>)$djE!14S ze$&kpnHM-)n>{7e=gsa~7Bz2u9v8ur}OM&o$vC@ z$iVln;zB)7jYW*!J3UrDRXlvQJ>`bTV=3ld?hB@7MHhJf&1j6BC=*?`i0SUjlbue ztom<|oyDH8(;;x$5A!XZrzUQhsyth;=FGBMi)quG7P(k1dbRnbLr|9CBbzE&Rog3V zJlvKI2Pfk{)a0gWF`Fiq?ig|zCv#7lEKejT#wtS5o+B+}mF{r6I?&_!>&qMfHkspIAKgJzK{n3;yhFg$Mg3?zzwTtShhZ zYVAfu(zmMy1vHFG{waVJmZgx&hh@;c`?DzoNIoG4tcH{`txRYEsL7BK97sz5qD5*=VaIIleHO@>R$`HtQTfAeaj*@;n746 z>yI${439R$wzbWSN3S%`*N-gXR_r{J znlS5^vs3J(02k)IqKQGLo!e&fpWL8%%(TZu&*A!w6OP6|lG(~!i*gPgUT4$GT>sZF z`j^w6W!KL&zGskZIaa^RNUbD!x2&(Zk`*J$)FdVIsa9Nfe zxtI00O3aCEOJrLPiqG?T{))GTi@*KAoH=inR(jhVO|bi4^!4Ymi^ATFRvt^MTRYVh zT@{5jF5JpZJ8II`C1MuE9+)WC-L-SW+b_!EBClVb*?IG>*4yZ*f#nD4+w*?1ysK6d zKXiD_O4)|TOs|3v9@OpX8T5M(_9dbi+t>4bCjrHo;AK2WMb>%STJ`cU&d?$KFg;7-0vT5dwDYI6@ zT?^DnEWaW10^We7sg(=i$r$&ZpGutC(j#&|Ep8 z{_+fA|9$gvirpnG13s`$IuJb&l3+miMC$FrkkvyZ2* zvTI(L>gs&VWn=hnJ!{#k8)q>q%++2zF^REq%cr{xfnv`ezA@ALA$a(ANAW&Uw~ngp z*potPyJA@%^{OYRIlg7BJR^9e@}PsT>*e!|y2kZqdQul>WQqLS}KohG{eJPkxb6wY&ZCZy_~>>D^5da~E(wdA)4i zN>{ne!Yv;p=5}T8s^Cxp%o4*#<{