Skip to content

Commit

Permalink
Merge pull request #3 from 5150VEX/unit-coercion
Browse files Browse the repository at this point in the history
Add unit_cast, to_linear, and to_angular functions
  • Loading branch information
Aang099 authored May 31, 2024
2 parents 3416834 + c879979 commit a34ae66
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
27 changes: 26 additions & 1 deletion include/units/units.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ template <TYPENAMES> void quantityChecker(Quantity<DIMS> q) {}
template <typename Q>
concept isQuantity = requires(Q q) { quantityChecker(q); };

// Un(type)safely coerce the a unit into a different unit
template <isQuantity Q1, isQuantity Q2> constexpr inline Q1 unit_cast(Q2 quantity) { return Q1(quantity.val()); }

template <isQuantity Q1, isQuantity Q2> using QMultiplication = Quantity<
std::ratio_add<typename Q1::mass, typename Q2::mass>, std::ratio_add<typename Q1::length, typename Q2::length>,
std::ratio_add<typename Q1::time, typename Q2::time>, std::ratio_add<typename Q1::current, typename Q2::current>,
Expand Down Expand Up @@ -308,4 +311,26 @@ template <isQuantity Q> constexpr Q trunc(const Q& lhs, const Q& rhs) {
template <isQuantity Q> constexpr Q round(const Q& lhs, const Q& rhs) {
return Q(std::round(lhs.val() / rhs.val()) * rhs.val());
}
} // namespace units
} // namespace units

// Convert an angular unit `Q` to a linear unit correctly;
// mostly useful for velocities
template <isQuantity Q>
Quantity<typename Q::mass, typename Q::angle, typename Q::time, typename Q::current, typename Q::length> toLinear(
Quantity<typename Q::mass, typename Q::length, typename Q::time, typename Q::current, typename Q::angle> angular,
Length diameter) {
return unit_cast<
Quantity<typename Q::mass, typename Q::angle, typename Q::time, typename Q::current, typename Q::length>>(
angular * (diameter / 2.0));
}

// Convert an linear unit `Q` to a angular unit correctly;
// mostly useful for velocities
template <isQuantity Q>
Quantity<typename Q::mass, typename Q::angle, typename Q::time, typename Q::current, typename Q::length> toAngular(
Quantity<typename Q::mass, typename Q::length, typename Q::time, typename Q::current, typename Q::angle> linear,
Length diameter) {
return unit_cast<
Quantity<typename Q::mass, typename Q::angle, typename Q::time, typename Q::current, typename Q::length>>(
linear / (diameter / 2.0));
}
4 changes: 4 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ void initialize() {
num = 0.0;
a.theta().convert(deg);
to_cDeg(a.theta());

Length x = unit_cast<Length>(num);
Angle y = toAngular<Length>(x, 2_cm);
Length z = toLinear<Angle>(y, 2_cm);
}

/**
Expand Down

0 comments on commit a34ae66

Please sign in to comment.