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.
All of the above dimensions have to be marked as final.
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.
All of the above quantity specifications have to be marked as final.
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.
All of the above units have to be marked as final.
Note
In the mp-units library, physical constants are also implemented as units.
AssociatedUnit<T>¶
AssociatedUnit concept describes a unit with an associated quantity
and is satisfied by:
- All units derived from a
named_unitclass template instantiated with a unique symbol identifier and aQuantitySpecof a quantity kind. - All units being a result of unit equations on other associated units.
Examples
All units in the SI have associated quantities. For example,
si::second is specified to measure isq::time.
Natural units typically do not have an associated quantity. For example, if we assume c = 1,
a natural::second unit can be used to measure both time and length. In such case, speed
would have a unit of one.
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:
- An
AssociatedUnit. - 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 constraints a type of a number that stores the
value of a quantity and is satisfied:
-
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.
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:
inline constexpr struct mean_sea_level final : absolute_point_origin<isq::altitude> {} mean_sea_level;
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_ final : 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;