|
Unit Conversion and Dimensional Analysis Library 3.6.1
A compile-time, header-only C++23 dimensional-analysis library
|
The user-defined literal operators — 5.0_m, 3_km, 2.0_Te — the scheme that names them, and the metric prefixes they carry.
Every unit in the library gets a user-defined literal operator named _<abbreviation>, where the abbreviation is the unit's short form (m for meters, s for seconds, N for newtons). The literals let a quantity be written as a suffixed numeric literal instead of a constructor call.
The literal operators are declared in the nested namespace units::literals, kept separate from the rest of the library so that pulling them in is an explicit, opt-in decision. A literal suffix is only visible once that namespace is in scope:
Without the using directive, 5.0_m fails to compile with "unable to find numeric literal operator ""_m". You may scope the directive to a function or a block rather than a whole file; ADL does not apply to literal operators, so the directive is the only way to reach them.
Note: The literals are generated by the same UNIT_ADD machinery that defines a unit, so a unit you define yourself automatically gets its own _<abbreviation> literal in units::literals. Defining UNIT_NO_LITERAL_SUPPORT (see configuration) suppresses generation of every literal operator.
Each unit declares two literal operators — one taking long double, one taking unsigned long long — and the form of the numeric literal selects between them:
Caveat: An integer-representation quantity refuses a lossy implicit conversion. meters<int> x = 1.0_ft; is ill-formed because feet-to-meters would truncate in an integer. When in doubt — especially for anything that will be converted or divided — prefer the floating-point form (5.0_m), which imposes no such restriction.
A unit defined with metric prefixes (via UNIT_ADD_WITH_METRIC_PREFIXES) gets a literal for each SI prefix from femto to peta. The literal suffix is _<prefix-symbol><abbreviation> — the prefix symbol prepended to the unit's abbreviation. So meters (_m) also yields _km (kilometers), _mm (millimeters), _um (micrometers), and so on.
| Prefix | Symbol | Factor | Example literal |
|---|---|---|---|
| femto | f | 10⁻¹⁵ | 1.0_fm |
| pico | p | 10⁻¹² | 1.0_pm |
| nano | n | 10⁻⁹ | 1.0_nm |
| micro | u | 10⁻⁶ | 1.0_um |
| milli | m | 10⁻³ | 250_mm |
| centi | c | 10⁻² | 1.0_cm |
| deci | d | 10⁻¹ | 1.0_dm |
| deca | da | 10¹ | 1.0_dam |
| hecto | h | 10² | 1.0_hm |
| kilo | k | 10³ | 3.0_km |
| mega | M | 10⁶ | 1.0_Mm |
| giga | G | 10⁹ | 1.0_Gm |
| tera | T | 10¹² | 1.0_Tm |
| peta | P | 10¹⁵ | 1.0_Pm |
Note: micro uses the ASCII symbol u (_um), not the Greek µ, so the literal is typable on any keyboard. The prefix symbols are case-sensitive: _Mm (megameters) and _mm (millimeters) are different literals, as SI intends.
Tesla is the one unit whose literal is not its plain abbreviation. Its abbreviation would be T, but _T collides with a preprocessor macro named _T (the TCHAR text macro from the Windows headers, <tchar.h>/<windows.h>). To avoid that clash, tesla uses Te, so its literal is _Te:
Because tesla is prefix-enabled, its prefixed literals prepend the prefix symbol to Te — e.g. _mTe (millitesla), _uTe (microtesla). The T (tera) prefix is unaffected on other units: _Tm is terameters, _Ts is teraseconds.
Caveat: The _T clash is a Windows/<tchar.h> concern (also seen on some ARM toolchains that define _T). It is the reason for the Te spelling; do not expect a _T tesla literal on any platform.