1 Scope [scope]

This document describes the contents of the mp-units library.

2 References [refs]

The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document.
For dated references, only the edition cited applies.
For undated references, the latest edition of the referenced document (including any amendments) applies.
  • IEC 60050-102:2007/AMD3:2021, Amendment 3 — International Electrotechnical Vocabulary (IEV) — Part 102: Mathematics — General concepts and linear algebra
  • IEC 60050-112:2010/AMD2:2020, Amendment 2 — International Electrotechnical Vocabulary (IEV) — Part 112: Quantities and units
  • ISO 80000 (all parts), Quantities and units
  • The C++ Standards Committee.
    N4971: Working Draft, Standard for Programming Language C++.
    Edited by Thomas Köppe.
    Available from: https://wg21.link/N4971
  • The C++ Standards Committee.
    SD-8: Standard Library Compatibility.
    Edited by Bryce Lelbach.
    Available from: https://wg21.link/SD8

3 Terms and definitions [defs]

For the purposes of this document, the terms and definitions given in IEC 60050-102:2007/AMD3:2021, IEC 60050-112:2010/AMD2:2020, ISO 80000-2:2019, and N4971, and the following apply.
ISO and IEC maintain terminology databases for use in standardization at the following addresses:

4 Specification [spec]

4.1 External [spec.ext]

The specification of the mp-units library subsumes N4971, [description], N4971, [requirements], N4971, [concepts.equality], and SD-8, all assumingly amended for the context of this library.
[Note 1: 
This means that, non exhaustively,
  • ​::​mp_units2 is a reserved namespace, and
  • std​::​vector<mp_units​::​type> is a program-defined specialization and a library-defined specialization from the point of view of the C++ standard library and the mp-units library, respectively.
— end note]
The mp-units library is not part of the C++ implementation.

4.2 Categories [spec.cats]

Detailed specifications for each of the components in the library are in [qties][qties], as shown in Table 1.
Table 1: Library categories [tab:lib.cats]
Clause
Category
Quantities library
The quantities library ([qties]) describes components for dealing with quantities.

4.3 Modules [spec.mods]

The mp-units library provides the mp-units modules, shown in Table 2.
Table 2: mp-units modules [tab:modules]
mp_units
mp_units.core
mp_units.systems

4.4 Library-wide requirements [spec.reqs]

4.4.1 Reserved names [spec.res.names]

The mp-units library reserves macro names that start with MP_UNITSdigit-sequence_.

5 Quantities library [qties]

5.1 Summary [qties.summary]

This Clause describes components for dealing with quantities, as summarized in Table 3.
Table 3: Quantities library summary [tab:qties.summary]
Subclause
Module
Helpers
mp_units.core
Traits
Concepts
Types
Compatibility
Dimension one
Systems
mp_units.systems
std​::​chrono compatibility

5.2 Module mp_units synopsis [mp.units.syn]

export module mp_units; export import mp_units.core; export import mp_units.systems;

5.3 Module mp_units.core synopsis [mp.units.core.syn]

export module mp_units.core; import std; export namespace mp_units { export enum class quantity_character { scalar, vector, tensor }; // [qty.traits], traits template<typename Rep> constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>; template<typename Rep> constexpr bool is_scalar = std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>); template<typename Rep> constexpr bool is_vector = false; template<typename Rep> constexpr bool is_tensor = false; template<typename Rep> struct quantity_values; template<typename T> struct quantity_like_traits; template<typename T> struct quantity_point_like_traits; // [qty.concepts], concepts template<typename T> concept some_reference = template_of(^std::remove_cvref_t<T>) == ^reference; template<typename T> concept representation = see below; template<typename T, quantity_character Ch> concept representation_of = see below; template<typename T> concept some_quantity_spec = see below; // [qty.types], types template<auto...> struct quantity_spec; // not defined template<auto Q> struct kind_of_; // not defined template<unspecified... Expr> struct derived_quantity_spec; // [qty.type], class template quantity export template<some_reference auto R, representation_of<get_quantity_spec(R).character> Rep = double> class quantity; // [qty.point.type], class template quantity_point template<unspecified> class quantity_point; }

5.4 Module mp_units.systems synopsis [mp.units.systems.syn]

export module mp_units.systems; export import mp_units.core; import std; export namespace mp_units { }

5.5 Helpers [qty.helpers]

consteval bool converts-to-base-subobject-of(std::meta type, std::meta template_name);
Preconditions: is_type(type) && is_template(template_name) is true.
Returns: true if [:type:] has an unambiguous and accessible base that is a specialization of [:template_name:], and false otherwise.

5.6 Traits [qty.traits]

template<typename Rep> constexpr bool is_scalar = std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>); template<typename Rep> constexpr bool is_vector = false; template<typename Rep> constexpr bool is_tensor = false;
Remarks: Pursuant to N4971, [namespace.std] ([spec.ext]), users may specialize is_scalar, is_vector, and is_tensor to true for cv-unqualified program-defined types which respectively represent a scalar (IEC 60050, 102-02-18), a vector (IEC 60050, 102-03-04), and a tensor, and false for types which respectively do not.

5.7 Concepts [qty.concepts]

export template<typename T> concept representation = (is_scalar<T> || is_vector<T> || is_tensor<T>)&&std::regular<T> && scalable<T>;
export template<typename T, quantity_character Ch> concept representation_of = representation<T> && ((Ch == quantity_character::scalar && is_scalar<T>) || (Ch == quantity_character::vector && is_vector<T>) || (Ch == quantity_character::tensor && is_tensor<T>));
template<typename T> concept named-quantity-spec = (converts-to-base-subobject-of(^T, ^quantity_spec) && template_of(^T) != ^kind_of_); template<typename T> concept some_quantity_spec = named-quantity-spec<T> || detail::IntermediateDerivedQuantitySpec<T> || template_of(^T) == ^kind_of;

5.8 Types [qty.types]

5.8.1 General [qty.types.general]

A quantity type is a type Q that is a specialization of quantity or quantity_point.
Q represents a quantity (IEC 60050, 112-01-01) with Q​::​rep as its number and Q​::​reference as its reference.
Q is a structural type (N4971, [temp.param]) if Q​::​rep is a structural type.
Each class template defined in subclause [qty.types] has data members and special members specified below, and has no base classes or members other than those specified.

5.8.2 Class template quantity [qty.type]

namespace mp_units { export template<some_reference auto R, representation_of<get_quantity_spec(R).character> Rep = double> class quantity { unspecified }; }
Let Q be a specialization of quantity.

5.8.3 Class template quantity_point [qty.point.type]

namespace mp_units { export template<unspecified> class quantity_point { unspecified }; }
A quantity point type is a specialization of quantity_point.
Let Q be a quantity point type.
Q​::​point_origin represents the origin point of a position vector (IEC 60050, 102-03-15).
  • If Rep is a scalar, Q represents the scalar quantity (IEC 60050, 102-02-19) of a position vector.
  • If Rep is a vector, Q represents a position vector.

5.9 Compatibility [qty.compat]

5.10 Dimension one [qty.one]

5.12 std​::​chrono compatibility [qty.chrono]