The mp-units library might be the subject of ISO standardization for C++29. More on this can be found in the following ISO C++ proposals:
- P1935: A C++ Approach to Physical Units,
- P2980: A motivation, scope, and plan for a quantities and units library,
- P3045: Quantities and units library.
We are actively looking for parties interested in field-trialing the library.
A brief introduction to the library's interfaces and the rationale for changes in the version 2.0 ofmp-unitswere provided in detail byMateusz Puszin the "The Power of C++ Templates With mp-units: Lessons Learned & a New Library Design" talk at the C++ on Sea 2023 conference.
An extensive project documentation can be found onmp-units GitHub Pages. It includes installation instructions and a detailed user's guide.
This project uses the official metrology vocabulary defined by the ISO and BIPM. Please familiarize yourself with those terms to better understand the documentation and improve domain-related communication and discussions. You can find essential project-related definitions inour documentation's "Glossary" chapter. Even more terms are provided in the official vocabulary of theISO andBIPM.
mp-units
is a compile-time enabled Modern C++ library that provides compile-time dimensional
analysis and unit/quantity manipulation.
Here is a small example of possible operations:
#include<mp-units/systems/si.h>
usingnamespacemp_units;
usingnamespacemp_units::si::unit_symbols;
//simple numeric operations
static_assert(10* km /2==5* km);
//conversions to common units
static_assert(1* h ==3600* s);
static_assert(1* km +1* m ==1001* m);
//derived quantities
static_assert(1* km / (1* s) == 1000 * m / s);
static_assert(2* km / h * (2* h) == 4 * km);
static_assert(2* km / (2* km / h) == 1 * h);
static_assert(2* m * (3* m) == 6 * m2);
static_assert(10* km / (5* km) == 2 * one);
static_assert(1000/ (1* s) == 1 * kHz);
Try it on theCompiler Explorer.
This library heavily uses C++20 features (concepts, classes as NTTPs,...). Thanks to them the user gets a powerful but still easy to use interfaces and all unit conversions and dimensional analysis can be performed without sacrificing on runtime performance or accuracy. Please see the below example for a quick preview of basic library features:
#include<mp-units/format.h>
#include<mp-units/ostream.h>
#include<mp-units/systems/international.h>
#include<mp-units/systems/isq.h>
#include<mp-units/systems/si.h>
#include<format>
#include<iomanip>
#include<iostream>
#include<print>
usingnamespacemp_units;
constexprQuantityOf<isq::speed>autoavg_speed(QuantityOf<isq::length>autod,
QuantityOf<isq::time>autot)
{
returnd / t;
}
intmain()
{
usingnamespacemp_units::si::unit_symbols;
usingnamespacemp_units::international::unit_symbols;
constexprquantity v1 =110* km / h;
constexprquantity v2 =70* mph;
constexprquantity v3 =avg_speed(220.* isq::distance[km],2* h);
constexprquantity v4 =avg_speed(isq::distance(140.* mi),2* h);
constexprquantity v5 = v3.in(m / s);
constexprquantity v6 = value_cast<m / s>(v4);
constexprquantity v7 = value_cast<int>(v6);
std::cout << v1 <<'\n';//110 km/h
std::cout <<std::setw(10) <<std::setfill('*') << v2 <<'\n';//***70 mi/h
std::cout <<std::format("{:*^10}\n",v3);//*110 km/h*
std::println("{:%N in %U of %D}",v4);//70 in mi/h of LT⁻¹
std::println("{::N[.2f]}",v5);//30.56 m/s
std::println("{::N[.2f]U[dn]}",v6);//31.29 m⋅s⁻¹
std::println("{:%N}",v7);//31
}
Try it on theCompiler Explorer.