Concepts¶
This chapter enumerates all the user-facing concepts in the mp-units library.
Dimension<T>¶
Dimension concept matches a dimension of either a
base or derived quantity:
- Base dimensions are explicitly defined by the
user by inheriting from the instantiation of a
base_dimensionclass template. It should be instantiated with a unique symbol identifier describing this dimension in a specific system of quantities. - Derived dimensions are implicitly created by the library's framework based on the quantity equation provided in the quantity specification.
DimensionOf<T, V>¶
DimensionOf concept is satisfied when both arguments satisfy a Dimension
concept and when they compare equal.
QuantitySpec<T>¶
QuantitySpec concept matches all the
quantity specifications including:
- Base quantities defined by a user by inheriting
from the
quantity_specclass template instantiated with a base dimension argument. - Derived named quantities defined by a user
by inheriting from the
quantity_specclass template instantiated with a result of a quantity equation passed as an argument. - Other named quantities forming a
hierarchy of quantities of the same
kind defined by a user by inheriting from the
quantity_specclass template instantiated with another "parent" quantity specification passed as an argument. - Quantity kinds describing a family of mutually comparable quantities.
- Intermediate derived quantity specifications being a result of a quantity equations on other specifications.
QuantitySpecOf<T, V>¶
QuantitySpecOf concept is satisfied when both arguments satisfy a
QuantitySpec concept and when T is implicitly convertible to V.
UnitMagnitude<T>¶
UnitMagnitude concept is satisfied by all types defining a unit magnitude.
Info
Unit magnitude implementation is a private implementation detail of the library.
Unit<T>¶
Unit concept matches all the units in the library including:
- Base units defined by a user by inheriting from
the
named_unitclass template instantiated with a unique symbol identifier describing this unit in a specific system of units. - Named scaled units defined by a user by inheriting from the
named_unitclass template instantiated with a unique symbol identifier and a product of multiplying another unit with some magnitude. - Prefixed units defined by a user by inheriting from the
prefixed_unitclass template instantiated with a prefix symbol, a magnitude, and a unit to be prefixed. - Derived named units defined by a user by
inheriting from the
named_unitclass template instantiated with a unique symbol identifier and a result of unit equation passed as an argument. - Derived unnamed units being a result of a unit equations on other units.
- Physical constants defined by a user by inheriting from the
named_constantclass template instantiated with a unique symbol identifier and a product of multiplying another unit with some magnitude.
PrefixableUnit<T>¶
PrefixableUnit concept is satisfied by all units derived from a named_unit class template.
Such units can be passed as an argument to a prefixed_unit class template.
UnitOf<T, V>¶
UnitOf concept is satisfied for all units T for which an associated quantity spec is implicitly
convertible to the provided QuantitySpec value.
Reference<T>¶
Reference concept is satisfied by all quantity reference
types. Such types provide all the meta-information required to create a Quantity.
A Reference can either be:
- A
Unit. - The instantiation of a
referenceclass template with aQuantitySpecpassed as the first template argument and aUnitpassed as the second one.
ReferenceOf<T, V>¶
ReferenceOf concept is satisfied by references T which have a quantity specification
that satisfies QuantitySpecOf<V> concept.
RepresentationOf<T, V>¶
RepresentationOf concept constrains a type T of a number that stores the
numerical value of a quantity.
Every representation type must satisfy a common baseline:
- Weakly regular: copyable and equality comparable (default-constructibility is not required).
MagnitudeScalable: the library must be able to apply a unit magnitude ratio to it internally. Most standard types satisfy this automatically via the built-in scaling paths; custom types may additionally provideoperator*(T, UnitMagnitude)for magnitude-aware scaling that can change the representation type during unit conversion. See Representation Types for details.- Character-specific operations: additional arithmetic operations required by the
quantity character (e.g. total ordering for real
scalars,
real()/imag()/modulus()CPOs for complex scalars,norm()/magnitude()CPO for vectors).
The second template argument V further constrains which characters are accepted:
-
if the type of
VsatisfiesQuantitySpec:- by all representation types when
Vdescribes a quantity kind, - otherwise, by representation types that are of
a quantity character associated with a provided
quantity specification
V.
- by all representation types when
-
if
Vis ofquantity_charactertype:- by representation types that are of a provided quantity character.
See Representation Types for the full requirements and available customization points.
Quantity<T>¶
Quantity concept matches every
quantity in the library and is satisfied by all types
being or deriving from an instantiation of a quantity class template.
QuantityOf<T, V>¶
QuantityOf concept is satisfied by all the quantities for which a ReferenceOf<V>
is true.
QuantityLike<T>¶
QuantityLike concept provides interoperability with other libraries and is satisfied by a
type T for which an instantiation of quantity_like_traits type trait yields a valid type
that provides:
referencestatic data member that matches theReferenceconcept,reptype that matchesRepresentationOfconcept with the character provided inreference,explicit_importstatic data member convertible toboolthat specifies that the conversion fromTto aquantitytype should happen explicitly (iftrue),explicit_exportstatic data member convertible toboolthat specifies that the conversion from aquantitytype toTshould happen explicitly (iftrue),to_numerical_value(T)static member function returning a raw value of the quantity,from_numerical_value(rep)static member function returningT.
Examples
This is how support for std::chrono::seconds can be provided:
template<>
struct mp_units::quantity_like_traits<std::chrono::seconds> {
static constexpr auto reference = si::second;
static constexpr bool explicit_import = false;
static constexpr bool explicit_export = false;
using rep = std::chrono::seconds::rep;
[[nodiscard]] static constexpr rep to_numerical_value(const std::chrono::seconds& d)
{
return d.count();
}
[[nodiscard]] static constexpr std::chrono::seconds from_numerical_value(const rep& v)
{
return std::chrono::seconds(v);
}
};
quantity q = 42s;
std::chrono::seconds dur = 42 * s;
PointOrigin<T>¶
PointOrigin concept matches all
quantity point origins in the library. It is
satisfied by either:
- All types derived from an
absolute_point_originclass template. - All types derived from a
relative_point_originclass template.
PointOriginFor<T, V>¶
PointOriginFor concept is satisfied by all
PointOrigin types that have quantity type implicitly convertible from
quantity specification V, which means that V must satisfy
QuantitySpecOf<T::quantity_spec>.
Examples
si::ice_point can serve as a point origin for points of isq::Celsius_temperature because this
quantity type implicitly converts to isq::thermodynamic_temperature.
However, if we define mean_sea_level in the following way:
then it can't be used as a point origin for points of isq::length or isq::width as none of them
is implicitly convertible to isq::altitude:
- not every length is an altitude,
- width is not compatible with altitude.
QuantityPoint<T>¶
QuantityPoint concept is satisfied by all types being either a specialization or derived
from quantity_point class template.
QuantityPointOf<T, V>¶
QuantityPointOf concept is satisfied by all the quantity points T that match the
following value V:
V |
Condition |
|---|---|
QuantitySpec |
The quantity point quantity specification satisfies ReferenceOf<V> concept. |
PointOrigin |
The point and V have the same absolute point origin. |
QuantityPointLike<T>¶
QuantityPointLike concept provides interoperability with other libraries and is satisfied
by a type T for which an instantiation of quantity_point_like_traits type trait yields
a valid type that provides:
referencestatic data member that matches theReferenceconcept.point_originstatic data member that matches thePointOriginconcept.reptype that matchesRepresentationOfconcept with the character provided inreference.explicit_importstatic data member convertible toboolthat specifies that the conversion fromTto aquantity_pointtype should happen explicitly (iftrue),explicit_exportstatic data member convertible toboolthat specifies that the conversion from aquantity_pointtype toTshould happen explicitly (iftrue),to_numerical_value(T)static member function returning a raw value of the quantity being the offset of the point from the origin,from_numerical_value(rep)static member function returningT.
Examples
This is how support for a std::chrono::time_point of std::chrono::seconds can be provided:
template<typename C>
struct mp_units::quantity_point_like_traits<std::chrono::time_point<C, std::chrono::seconds>> {
static constexpr auto reference = si::second;
static constexpr struct point_origin_ : absolute_point_origin<isq::time> {} point_origin{};
static constexpr bool explicit_import = false;
static constexpr bool explicit_export = false;
using rep = std::chrono::seconds::rep;
using T = std::chrono::time_point<C, std::chrono::seconds>;
[[nodiscard]] static constexpr rep to_numerical_value(const T& tp)
{
return tp.time_since_epoch().count();
}
[[nodiscard]] static constexpr T from_numerical_value(const rep& v)
{
return T(std::chrono::seconds(v));
}
};
quantity_point qp = time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now());
std::chrono::sys_seconds q = qp + 42 * s;