mp-units
mp-units copied to clipboard
feat!: composable symbols
feat!: composable symbols
My original intent with "symbols" was to have composable 1-letter symbols that can describe units.
For example, m for metre and mm for millimetre, all with the same m
in code.
Instead, we got the product "unit prefix × unit symbol".
So on top of m
, we have mm
and m3
.
I think we should explore my original intent.
I'm not suggesting to remove mm
or m3
.
What I'm suggesting is to enable defining mm
in terms of m
.
This allows users to not have to pre-define prefixed versions of their units.
master |
feat! |
---|---|
x * m |
x * m |
x * mm |
x * m(m) |
There's only one m
(per system, so x * m
keeps meaning "x
SI metres").
Its meaning is contextual, much like in paper calculations.
The rules for composition are described in the SI Brochure §3 "Decimal multiples and sub-multiples of SI units".
Although m.m
is a possible syntax, m(m)
supports program-defined units such as M(px)
.
Abusing ^
for power:
master |
feat! |
clang-format s as |
---|---|---|
x * m3 |
x * (m^3) |
x * (m ^ 3) |
N/A | x * m(m^3) |
x * m(m ^ 3) |
Abusing ^
for power would require constexpr
parameters.
Lately, there's interest in that direction: https://github.com/cplusplus/papers/issues/1458#issuecomment-1812540792.
Examples:
An implementation using the version 2.0.0: https://godbolt.org/z/cd8qjrdxe.
#include <mp-units/systems/si/si.h>
using namespace mp_units;
using namespace mp_units::si::unit_symbols;
namespace ns {
template<template<PrefixableUnit auto U> class Prefix, Unit auto U> struct prefix_or_unit : decltype(U) {
template<PrefixableUnit U2> consteval Unit auto operator()(U2) const { return Prefix<U2{}>{}; }
};
inline constexpr struct m : prefix_or_unit<si::milli_, ::m> { } m;
}
static_assert(2 * m == 2 * ns::m);
static_assert(2 * mm == 2 * ns::m(ns::m));
master |
feat! |
---|---|
include/mp-units/systems/si/unit_symbols.h |
|
inline constexpr auto mm = milli<metre>; |
inline constexpr auto mm = m(m); |
example/spectroscopy_units.cpp |
|
isq::frequency(1. * THz) |
isq::frequency(1. * T(Hz)) |
isq::wavelength(1. * um) |
isq::wavelength(1. * u(m)) |
example/total_energy.cpp |
|
sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c))) |
^ for quantities too? |
isq::momentum(4. * GeV / c) |
isq::momentum(4. * G(eV) / c) |
QuantityOf<isq::mass> auto m1 = 3. * GeV / c2 |
QuantityOf<isq::mass> auto m1 = 3. * G(eV) / (c^2) |
p1.in(kg * m / s) |
p1.in(k(g) * m / s) |