5 Quantities and units library [quantities]

5.4 Reference [qty.ref]

5.4.3 Quantity specification [qty.spec]

5.4.3.6 Hierarchy algorithms [qty.spec.hier.algos]

5.4.3.6.1 Conversion [qty.spec.conv]

consteval bool implicitly_convertible(QuantitySpec auto from, QuantitySpec auto to);
Returns: TBD.
consteval bool explicitly_convertible(QuantitySpec auto from, QuantitySpec auto to);
Returns: TBD.
consteval bool castable(QuantitySpec auto from, QuantitySpec auto to);
Returns: TBD.
consteval bool interconvertible(QuantitySpec auto qs1, QuantitySpec auto qs2);
Returns: implicitly_convertible(qs1, qs2) && implicitly_convertible(qs2, qs1).

5.4.3.6.2 Get kind [qty.get.kind]

template<QuantitySpec Q> consteval QuantitySpec auto get-kind-tree-root(Q q); // exposition only
Returns:
  • If QuantityKindSpec<Q> is true, returns remove-kind(q).
  • Otherwise, if is-derived-from-specialization-of<Q, quantity_spec>() is true, and the specialization of Q​::​quantity_spec has a template argument equal to is_kind, returns q.
  • Otherwise, if Q​::​parent is a valid expression, returns get-kind-tree-root(Q​::​parent).
  • Otherwise, if DerivedQuantitySpec<Q> is true, returns expr-map<to-kind, derived_quantity_spec, struct dimensionless>(q) where to-kind is defined as follows: template<QuantitySpec Q> using to-kind = decltype(get-kind-tree-root(Q{})); // exposition only
  • Otherwise, returns q.
template<QuantitySpec Q> consteval QuantityKindSpec auto get_kind(Q);
Returns: kind_of<get-kind-tree-root(Q{})>.

5.4.3.6.3 Get common quantity specification [get.common.qty.spec]

consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto... qs) requires see below;
Let
  • q1 be qs...[0],
  • q2 be qs...[1],
  • Q1 be decltype(q1),
  • Q2 be decltype(q2), and
  • rest be a pack denoting the elements of qs without q1 and q2.
Effects: Equivalent to: if constexpr (sizeof...(qs) == 1) return q1; else if constexpr (sizeof...(qs) == 2) { using QQ1 = decltype(remove-kind(q1)); using QQ2 = decltype(remove-kind(q2)); if constexpr (std::is_same_v<Q1, Q2>) return q1; else if constexpr (NestedQuantityKindSpecOf<Q1{}, Q2{}>) return QQ1{}; else if constexpr (NestedQuantityKindSpecOf<Q2{}, Q1{}>) return QQ2{}; else if constexpr ((QuantityKindSpec<Q1> && !QuantityKindSpec<Q2>) || (DerivedQuantitySpec<QQ1> && NamedQuantitySpec<QQ2> && implicitly_convertible(Q1{}, Q2{}))) return q2; else if constexpr ((!QuantityKindSpec<Q1> && QuantityKindSpec<Q2>) || (NamedQuantitySpec<QQ1> && DerivedQuantitySpec<QQ2> && implicitly_convertible(Q2{}, Q1{}))) return q1; else if constexpr (constexpr auto common_base = get-common-base<Q1{}, Q2{}>()) return *common_base; else if constexpr (implicitly_convertible(Q1{}, Q2{})) return q2; else if constexpr (implicitly_convertible(Q2{}, Q1{})) return q1; else if constexpr (implicitly_convertible(get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{}))) return get-kind-tree-root(q2); else return get-kind-tree-root(q1); } else return get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...);
Remarks: The expression in the requires-clause is equivalent to: (sizeof...(qs) != 0 && (sizeof...(qs) == 1 || (sizeof...(qs) == 2 && (QuantitySpecConvertibleTo<get-kind-tree-root(Q1{}), get-kind-tree-root(Q2{})> || QuantitySpecConvertibleTo<get-kind-tree-root(Q2{}), get-kind-tree-root(Q1{})>)) || requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), rest...); }))

5.4.3.6.4 Get common base [qty.get.common.base]

In this subclause and [qty.is.child.of], let the kind of quantity (IEC 60050, 112-01-04) hierarchy of q be the tuple , where par is parent.
template<QuantitySpec auto A, QuantitySpec auto B> consteval auto get-common-base(); // exposition only
Let
  • be the number of elements in h(A),
  • be the number of elements in h(B),
  • s be ,
  • A be a tuple of the last s elements of h(A), and
  • B be a tuple of the last s elements of h(B).
Effects: Looks for x, the first pair-wise equal element in A and B.
Returns: std​::​optional(x), if x is found, and std​::​optional<unspecified>() otherwise.

5.4.3.6.5 Is child of [qty.is.child.of]

template<QuantitySpec Child, QuantitySpec Parent> consteval bool is-child-of(Child ch, Parent p); // exposition only
Returns: If h(p) has more elements than h(ch), returns false.
Otherwise, let C be a tuple of the last s elements of h(ch), where s is the number of elements in h(p).
Returns == p.