Units Library

The units library is a zero-overhead implementation of the International System of Units (SI) in C++. It provides strong typing of physical quantities with compile-time dimensional analysis.

namespace nin::inline units {
    struct dimension;
    template <dimension D, std::floating_point T = double> class quantity;
}

dimension

namespace nin::inline units {
    struct dimension;
}

Represents the physical dimension of a quantity as a tuple of seven integer exponents, one for each SI base quantity.

Data members

α
β
γ
δ
ε
ζ
η

SI base dimension exponents

int8_t α = 0

Time (second)

int8_t β = 0

Length (metre)

int8_t γ = 0

Mass (kilogram)

int8_t δ = 0

Electric current (ampere)

int8_t ε = 0

Temperature (kelvin)

int8_t ζ = 0

Amount of substance (mole)

int8_t η = 0

Luminous intensity (candela)

All default-initialized to 0 (dimensionless).

Member functions

operator ==

equality comparison

bool operator ==(dimension rhs) const

(1)

Returns true if all seven exponents are equal. Defaulted.

operator *=
operator /=

dimension arithmetic assignment

dimension & operator *=(dimension rhs)

(1)

dimension & operator /=(dimension rhs)

(2)

  • (1) Adds the exponents of rhs to *this (dimension multiplication).

  • (2) Subtracts the exponents of rhs from *this (dimension division).

sqrt

square root of a dimension

dimension sqrt() const

(1)

Returns a dimension with all exponents halved. Throws std::domain_error if any exponent is odd.

is_sqrt_ok

check if square root is valid

bool is_sqrt_ok() const

(1)

Returns true if all exponents are even.

Non-member functions

operator *
operator /

dimension arithmetic

dimension operator *(dimension lhs, dimension rhs)

(1)

dimension operator /(dimension lhs, dimension rhs)

(2)

  • (1) Returns a dimension with exponents summed.

  • (2) Returns a dimension with exponents subtracted.

quantity

namespace nin::inline units {
    template <dimension D, std::floating_point T = double>
    class quantity;
}

A physical quantity with a magnitude and a dimension. The magnitude is always stored internally in SI units, regardless of how the quantity was created.

Template parameters

  • D — A dimension specifying the physical dimension

  • T — A std::floating_point type for the magnitude (default: double)

Nested types

  • dimensions — The dimension D

  • floating_point_type — Same as T

Member functions

(Constructor)

constructs a quantity

quantity()

(1)

explicit(narrowing) quantity(quantity<D, T1> other)

(2)

  • (1) Default constructor. Magnitude is zero.

  • (2) Converting constructor from a quantity with the same dimension but different floating-point type. Explicit if the conversion is narrowing.

operator <⇒
operator ==

comparison operators

bool operator ==(quantity<D, T2> rhs) const

(1)

partial_ordering operator <⇒(quantity rhs) const

(2)

  • (1) Equality comparison (cross-type).

  • (2) Three-way comparison. Generates <, , >, >=.

operator +=
operator -=

addition and subtraction assignment

quantity & operator +=(quantity<D, T2> rhs)

(1)

quantity & operator -=(quantity<D, T2> rhs)

(2)

Adds or subtracts rhs from *this. The operands must have the same dimension.

operator *
operator /

multiplication and division with other quantities

quantity<D*D2> operator *(quantity<D2, T2> rhs) const

(1)

quantity<D/D2> operator /(quantity<D2, T2> rhs) const

(2)

  • (1) Returns a quantity whose dimension is the product of the two dimensions.

  • (2) Returns a quantity whose dimension is the quotient of the two dimensions.

There are no *= or /= operators for quantities with different dimensions, since the result type differs from *this.

operator *=
operator /=

scalar multiplication and division assignment

quantity & operator *=(T rhs)

(1)

quantity & operator /=(T rhs)

(2)

Multiplies or divides the magnitude by a scalar. Dimension is unchanged.

SI

magnitude in SI units

T SI() const

(1)

Returns the magnitude in the International System of Units.

CGS

magnitude in CGS units

T CGS() const

(1)

Returns the magnitude in the centimetre-gram-second system.

in

magnitude in a given unit

T in(quantity<D, T2> target_unit) const

(1)

Returns the magnitude expressed in target_unit. The target must have the same dimension.

Example
auto d = 1_km;
d.in(1_mi);  // ≈ 0.6214

degK
degC
degF

temperature conversions

T degK() const

(1)

T degC() const

(2)

T degF() const

(3)

Available only for quantities with temperature dimension.

  • (1) Returns the temperature in kelvin (same as SI()).

  • (2) Returns the temperature in degrees Celsius.

  • (3) Returns the temperature in degrees Fahrenheit.

operator T

implicit conversion to scalar

operator T() const

(1)

Available only for dimensionless quantities. Returns the magnitude as a scalar.

operator std::chrono::duration

conversion to chrono duration

operator std::chrono::duration<Rep, Period>() const

(1)

Available only for time quantities. Enables interoperability with <chrono>.

Non-member functions

operator +
operator -

unary operators

quantity operator +(quantity rhs)

(1)

quantity operator -(quantity rhs)

(2)

  • (1) Returns rhs unchanged.

  • (2) Returns rhs with negated magnitude.

operator +
operator -

binary addition and subtraction

quantity operator +(quantity lhs, quantity rhs)

(1)

quantity operator -(quantity lhs, quantity rhs)

(2)

Adds or subtracts two quantities of the same dimension.

operator *
operator /

scalar multiplication and division

quantity operator *(quantity lhs, arithmetic rhs)

(1)

quantity operator *(arithmetic lhs, quantity rhs)

(2)

quantity operator /(quantity lhs, arithmetic rhs)

(3)

quantity<1/D> operator /(arithmetic lhs, quantity rhs)

(4)

  • (1)-(3) Scale the quantity by a scalar. Dimension unchanged.

  • (4) Dividing a scalar by a quantity inverts the dimension.

abs
fabs

absolute value

quantity abs(quantity v)

(1)

quantity fabs(quantity v)

(2)

Returns the absolute value. Dimension unchanged.

sqrt

square root

quantity<D.sqrt()> sqrt(quantity v)

(1)

Returns the square root of the quantity. Halves each dimension exponent. Only available when all exponents are even.

hypot

hypotenuse / norm

quantity hypot(quantity v1, quantity v2)

(1)

quantity hypot(quantity v1, quantity v2, quantity v3)

(2)

  • (1) Returns \(\sqrt{v_1^2 + v_2^2}\).

  • (2) Returns \(\sqrt{v_1^2 + v_2^2 + v_3^2}\).

asin
acos
atan
atan2

inverse trigonometric functions

angle asin(T value)

(1)

angle acos(T value)

(2)

angle atan(T value)

(3)

angle atan(quantity<{}, T> value)

(4)

angle atan2(quantity num, quantity denom)

(5)

  • (1)-(3) Take a scalar and return an angle.

  • (4) Takes a dimensionless quantity and returns an angle.

  • (5) Takes two quantities of the same dimension and returns an angle.

Formatter

std::formatter<quantity<D, T>> supports format specifications:

  • Default: prints magnitude followed by the SI dimension string

  • Unit spec (e.g. {:_cm}): converts to the given unit before printing

  • Float spec (e.g. {:.3f}): applied to the magnitude

Literal operators

The library provides user-defined literal operators for all SI units with their prefixes. Considering all combinations of underlying types, prefixes, and units, there are more than 50,000 literals defined.

Naming convention

  • All literals start with _ (e.g. 1_m, 2.5_s)

  • SI prefixes are prepended (e.g. 1_km, 1_mm, 1_µm)

  • Floating-point type suffix: _f (float), none or _d (double), _l (long double)

  • Negative exponents use _ as a separator (e.g. _m_s for m/s, _m_s2 for m/s²)

SI prefixes

Prefix Symbol Factor

quecto

q

10-30

ronto

r

10-27

yocto

y

10-24

zepto

z

10-21

atto

a

10-18

femto

f

10-15

pico

p

10-12

nano

n

10-9

micro

µ

10-6

milli

m

10-3

centi

c

10-2

deci

d

10-1

deca

da

101

hecto

h

102

kilo

k

103

mega

M

106

giga

G

109

tera

T

1012

peta

P

1015

exa

E

1018

Factory functions

Factory functions provide the same functionality as literal operators but with a function call syntax. They are named as plurals or descriptive names.

Examples
auto d = nin::centimetres(3.0);   // 3 cm
auto t = nin::seconds(1.5);      // 1.5 s
auto v = nin::metres_v<float>(2.0f);  // 2 m as float

Type aliases

For each physical quantity, the library provides template and concrete aliases:

Pattern Example

name_v<T>

length_v<float> — template alias for any floating-point type

name

length — alias for name_v<double>

name_f

length_f — alias for name_v<float>

name_d

length_d — alias for name_v<double>

name_l

length_l — alias for name_v<long double>

Common type aliases

Alias Unit Dimension

time

second

T

length

metre

L

mass

kilogram

M

electric_current

ampere

I

temperature

kelvin

Θ

amount_of_substance

mole

N

luminous_intensity

candela

J

angle

radian

(dimensionless)

frequency

hertz

T-1

force

newton

M·L·T-2

pressure

pascal

M·L-1·T-2

energy

joule

M·L2·T-2

power

watt

M·L2·T-3

electric_charge

coulomb

T·I

voltage

volt

M·L2·T-3·I-1

Physical constants

Mathematical and physical constants are provided as constexpr variables.

Mathematical constants

Name Value

π

3.14159265…​

2.71828182…​

π_rad

π radians

SI defining constants

Name Description

c

Speed of light (299,792,458 m/s)

Planck constant

e

Elementary charge

k

Boltzmann constant

N_A

Avogadro constant

K_cd

Luminous efficacy

Derived constants

Name Description

Reduced Planck constant

G

Gravitational constant

μ_0

Permeability of free space

ε_0

Permittivity of free space

R

Molar gas constant

F

Faraday constant

σ

Stefan-Boltzmann constant

g

Standard acceleration due to gravity

m_e

Electron mass

m_p

Proton mass

Conformance

The units and fundamental constants are taken from:

"The International System of Units" 9th edition (2019).

Other physical constants are from:

Tiesinga, E., Mohr, P. J., Newell, D. B., & Taylor, B. N. (2021). CODATA recommended quantities of the fundamental physical constants: 2018. Reviews of Modern Physics, 93(2), 025010.

Any deviation from these documents shall be considered a bug.