GitHub - mpusz/mp-units: The Domain-Correct Quantities and Units Library for C++ β€” full quantity kind safety, ISO 80000 compliant, C++29 standardization candidate.

logo

License C++ Standard

Conan CI CMake CI clang-tidy CI Freestanding CI Formatting CI Documentation

Conan Center Conan testing

🎯 Overview

mp-units is the only Modern C++ (C++20 and later) library providing the full spectrum of compile‑time safety for domain-specific quantities and units β€” from dimensional analysis to quantity kind safety β€” built on the ISO 80000 International System of Quantities (ISQ). It is the leading candidate for C++29 standardization β€” your chance to shape the future of C++.

#include <mp-units/systems/isq.h>
#include <mp-units/systems/si.h>

using namespace mp_units;
using namespace mp_units::si::unit_symbols;

// Compile-time dimensional analysis β€” zero runtime overhead
static_assert(1 * km / (1 * s) == 1000 * m / s);

// Function signatures encode domain/physics, not just dimensions
void calculate_trajectory(quantity<isq::kinetic_energy[J]> e);

int main()
{
  quantity<isq::potential_energy[J]> Ep = 42 * J;
  quantity<isq::kinetic_energy[J]>   Ek = 123 * J;
  calculate_trajectory(Ek);         // βœ… correct
  // calculate_trajectory(Ep);      // ❌ potential energy β‰  kinetic energy (both in J)

  // quantity<Gy> q = 42 * Sv;      // ❌ absorbed dose β‰  dose equivalent (both J/kg)
}

Try it live on Compiler Explorer

What Sets mp-units Apart?

Beyond standard dimensional analysis and automatic unit conversions, mp-units provides safety levels available in no other C++ library:

  • πŸ₯‡ The only C++ library with Quantity Kind Safety β€” Distinguishes quantities that share the same dimension but represent fundamentally different physical concepts: frequency (Hz) β‰  radioactive activity (Bq), absorbed dose (Gy) β‰  dose equivalent (Sv), plane angle (rad) β‰  solid angle (sr). Dimensional analysis alone cannot catch these errors β€” mp-units prevents them at compile time.

  • πŸ₯‡ The only library implementing ISO 80000 (ISQ) β€” Built on the International System of Quantities, functions can require specific quantities: isq::height (not just any isq::length), isq::kinetic_energy (not just any isq::energy). The physics of your domain becomes part of the type system.

  • πŸ₯‡ Strongly-Typed Numerics for Any Domain β€” The quantity framework extends beyond physics: define semantically distinct types for item counts, financial values, identifiers, or any numeric abstraction that should never be silently mixed at compile time.

πŸ’‘ Examples

mp-units provides an expressive, readable API that feels natural to write while catching entire classes of bugs at compile time.

Unit Arithmetic

Here's a taste of what mp-units can do:

#include <mp-units/systems/si.h>

using namespace mp_units;
using namespace mp_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 live on Compiler Explorer

Modern C++ Design

The library makes extensive use of C++20 features (concepts, class types as NTTPs, etc.). This enables powerful yet easy‑to‑use interfaces while performing all conversions and dimensional analysis at compile time β€” without sacrificing runtime performance or accuracy. The example below showcases ISQ quantity types, mixed unit systems, and rich text formatting:

#include <mp-units/systems/isq.h>
#include <mp-units/systems/si.h>
#include <mp-units/systems/yard_pound.h>
#include <format>
#include <iomanip>
#include <iostream>
#include <print>

using namespace mp_units;

constexpr QuantityOf<isq::speed> auto avg_speed(QuantityOf<isq::length> auto d,
                                                QuantityOf<isq::duration> auto t)
{
  return d / t;
}

int main()
{
  using namespace mp_units::si::unit_symbols;
  using namespace mp_units::yard_pound::unit_symbols;

  constexpr quantity v1 = 110 * km / h;
  constexpr quantity v2 = 70 * mph;
  constexpr quantity v3 = avg_speed(220. * isq::distance[km], 2 * h);
  constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * h);
  constexpr quantity v5 = v3.in(m / s);
  constexpr quantity v6 = value_cast<m / s>(v4);
  constexpr quantity 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 live on Compiler Explorer

βœ… Key Features

Safety

  • Quantity kind safety: same dimension, different meaning β†’ compile-time error
  • Affine space strong types (quantity and quantity_point)
  • Value-preserving conversions

Performance

  • All dimensional analysis at compile time β€” zero runtime overhead
  • Performance on par with (sometimes even better than) fundamental types

User Experience

  • Optimized for readable, actionable compilation errors
  • Expressive, composable unit expressions

Feature Rich

  • Systems of Quantities and Units; scalar, vector, and tensor quantities
  • Affine space, natural units, strong angular system
  • Highly adjustable text output formatting

Easy to Extend

  • Custom dimensions, quantities, and units in a single line of code

Low Adoption Cost

  • No external dependencies Β· macro-free API Β· C++20 modules-ready Β· freestanding-capable

β†’ Full feature overview

πŸ“š Documentation

Extensive project documentation covers everything from getting started to advanced usage:

  • Installation instructions – Get up and running quickly
  • Detailed user's guide – Comprehensive usage documentation
  • Design rationale – Understanding the architectural decisions
  • API reference – Complete technical documentation
  • Tutorials – Step-by-step learning resources
  • Workshops – Hands-on practice exercises
  • Examples – Real-world usage demonstrations

β†’ Explore the full documentation

πŸ” Try It Out

For advanced development or contributions, we provide a fully configured cloud development environment with GitHub Codespaces:

Open in GitHub Codespaces

Alternatives:

  1. Navigate to the repository β†’ "Code" β†’ "Codespaces" β†’ "Create codespace on master"
  2. Use the pre‑configured devcontainer and Docker image manually in your IDE

For detailed environment documentation, see .devcontainer/README.md.

πŸš€ Help Shape the Future of C++

mp-units is a candidate for ISO standardization for C++29 β€” the future of dimensional analysis in C++! The technical case is documented in:

🀝 We are actively seeking organizations and individuals interested in field‑trialing the library!

Your experience matters. Real-world testimonials demonstrate value to the ISO C++ Committee and help potential adopters decide. Whether you're using mp-units in production, research, or education:

  • Organizations: Share your production deployments and success stories
  • Academics: Report research applications and teaching experiences
  • Developers: Tell us about your innovative use cases and benefits

Share Experience

🀝 Contributors

mp-units is made possible by our amazing community of contributors! πŸ’ͺ

Contributors Commits Stars

πŸ† Core Team

πŸ™ All Contributors

We appreciate every contribution, from code to documentation to community support!

🌟 See our Contributors Page for the complete list and recognition details.

Ready to contribute? Check out our Contributing Guide to get started! πŸš€

πŸ’ Support the Project

mp-units is developed as open source with the ambitious goal of C++29 standardization. Your support helps maintain development momentum and accelerate standardization efforts!

Ways to support:

  • ⭐ Star the repository – Show your appreciation and help others discover mp-units

  • πŸ’° Become a sponsor – Financial support enables continued development

    Sponsor

  • πŸ“’ Share your success story – Help demonstrate real-world value for standardization and other potential users

  • 🀝 Contribute – Code, documentation, feedback, and community support