Skip to content

mp-units 2.5.0 released

A new product version can be obtained from GitHub and Conan.

I initially had different plans for this release, but during development it turned out that the new big feature I was working on was too big and will require some breaking changes. This put me off tracks, and unfortunately the mp-units development slowed down recently 😞

It also turned out that I got unemployed, so now I depend solely on my C++ trainer's career to earn money for living. Fortunately, I delivered many in-house C++ trainings to my customers this year, and I hope this will also be the case for the upcoming 2026. I was also busy with preparations of new talks and classes for this year's C++ conferences.

Having that much on my plate, a break from mp-units was needed to not burn out on the way. But hopefully I am back now and I plan to continue working on long awaited features now.

Said that, if you care about mp-units and would like to see it grow faster, please either contribute or consider sponsoring my work.

This release contains a lot of small patches and improvements.

This post describes the most significant changes while a much longer list of the changes introduced by the new version can be found in our Release Notes.

Representation concepts improved

First, handling of custom representation types has been changed. We no longer have to specialize is_scalar, is_vector, and is_tensor customization points for custom representation types. Their character will be deduced from the types interface now.

To enable detection of the following representation categories we provided new CPOs:

  • ComplexScalar requires all of the bellow:

    • real - CPO that checks for member or non-member function real(),
    • imag - CPO that checks for member or non-member function imag(),
    • modulus - CPO that checks for member or non-member functions modulus() or abs() (to support std::complex).
  • RealScalar is the types that provide scalar like interface and do not satisfy ComplexScalar concept

    • Additionally any type that accidentally provides such interfaces, but should not be used as a real scalar quantity representation, may opt-off from this concept by specializing the disable_real<> customization point.

      For example, we are doing this for a bool type already:

      template<> constexpr bool disable_real<bool> = true;
      
  • Vector requires the type to be compatible with the magnitude CPO which checks for member or non-member function magnitude(). Moreover, to allow using real types to represent one-dimensional vector quantities it also checks if the type satisfies RealScalar concept and:

    • if the type satisfies std::is_arithmetic it uses std::abs(),
    • otherwise, it looks for member or non-member function abs().

We've also removed the Representation concept (💥 breaking change 💥). It turned out to not be that useful.

Additionally, RepresentationOf concept now takes QuantitySpec (instead of quantity_character) (💥 breaking change 💥) which allowed us to accept representation type of any character for quantity kinds (when just unit is used and no specific quantity_spec is provided). For example, this allows us the following:

// quantity kind (any quantity type of kind length)
quantity q1 = 10 * m;
quantity q2 = cartesian_vector(1, 2, 3) * m;

// vector quantity
quantity q3 = isq::displacement(10 * m);
quantity q4 = isq::displacement(cartesian_vector(1, 2, 3) * m);

// scalar quantity
quantity q5 = isq::width(10 * m);
// quantity q6 = isq::width(cartesian_vector(1, 2, 3) * m);  // Compile-time error

As we can see above, in this release we are allowed to use a vector representation type for q2 as we do not know a specific type of this quantity. We just know that it is some kind of length. Using a vector quantity for q6 is not allowed as isq::width is defined as a scalar quantity.

On the other hand, this release also allows us to use scalar types for vector quantities, so in case of q3 we can use int for isq::displacement even though it is defined as a vector quantity. In this case an int is considered a one-dimensional vector type.

Info

To enable vector quantities usage we have added a very simple cartesian_vector representation type in this release.

quantity_values renamed to representation_values (breaking change)

std::numeric_limits support added

This releases introduces proper std::numeric_limits support. The default implementation just uses the numerical properties of the underlying representation types.

quantity::one() removed

  • not really an identity (only for dimensionless[one])
  • use representation_values<Rep>::one() * Unit
  • breaking change

first_known_factor no longer needed

We can prime-factorize every rational magnitude now. Thanks @chiphogg!

New quantity specs conversion rules

Subkinds are no longer implicitly convertible to parrent kind Convertiblility of ingredients is now better preserved in derived types.

absolute renamed to point

lerp and midpoint for points added

  • isq::displacement and isq::position_vector moved to other places in the tree.
  • isq::velocity definition fixed to use isq::displacement instead of isq::position_vector
  • electromagnetism updated to the IEC 80000-6-2022
  • complex characters properly applied to all complex electromagnetism quantities

std::numeric_limits support added

scaling_overflows_non_zero_values added to detect conversions overflowing rep

amazing API Reference by @JohelEGP

is_value_preserving customization point added

explicit constructor now can perform an explicit quantity_spec conversion

natural units support is now opt-in

value_type_t is now recursive

invoke_with_prefixed added to SI

measurement.h extracted for easier reuse

clcpp_response and conversion_factor examples removed

type_list moved to implementation details (breaking)

from now unit_symbol and dimension_symbol always returns

std::string_view (breaking)

text_encoding renamed to character_set (breaking)

Magnitude renamed to UnitMagnitude and magnitude to detail::unit_magnitude (breaking)

absolute renamed to point (breaking)

scalar and complex characters renamed to real_scalar and complex_scalar respectively + concepts refactoring (breaking)

MagConstant concept renamed to detail::is_mag_constant variable trait (breaking)

format.h and ostream.h header files deprecated (breaking)

rename default_denominator to default_solidus in unit_symbol_solidus enum

Breaking changes to quantity specs: - electric_current_phasor, voltage_phasor, apparent_power switched to complex character - position_vector and displacement moved to a different place in a tree - velocity is now defined in terms of displacement instead of position_vector

Lot's of improved and new docs: - tutorials - examples reworked - cheat sheet - CONTRIBUTORS.md

CodeSpaces support added (GitPod removed)

CI matrix generation added (thanks @burnpanck)

GitHub templates for Issues (bug reports, documentation issues, feature requests, and usage experience) and PRs.

Ask the users to provide usage experience (described in README) and fund the project if possible.

Comments