Allow units to be scaled by an unitless quantity

This allows Unit<> and AxisUnit<> to be scaled with a fraction as
expected, promoting the scaler to the same unit:

  0.2_mm * 10 => 2_mm (mm*f => mm)

Multiplication type is commutative:

  10 * 0.2_mm => 2_mm (f*mm => mm)

Division isn't:

  0.2_mm / 10 => 0.02_mm (mm*1/f => mm)
  10 / 0.2_mm => error (illegal type conversion)
pull/66/head
Yuri D'Elia 2021-07-30 00:51:51 +02:00 committed by DRracer
parent fae7dead93
commit 7dcd4975e1
2 changed files with 28 additions and 10 deletions

View File

@ -73,13 +73,22 @@ struct AxisUnit {
typedef T type_t;
typedef AxisUnit<T, A, U> self_t;
constexpr self_t operator+(const self_t r) { return { v + r.v }; }
constexpr self_t operator-(const self_t r) { return { v - r.v }; }
constexpr self_t operator-() { return { -v }; }
constexpr self_t operator*(const self_t r) { return { v * r.v }; }
constexpr self_t operator/(const self_t r) { return { v / r.v }; }
// same-type operations
constexpr self_t operator+(const self_t r) const { return { v + r.v }; }
constexpr self_t operator-(const self_t r) const { return { v - r.v }; }
constexpr self_t operator-() const { return { -v }; }
constexpr self_t operator*(const self_t r) const { return { v * r.v }; }
constexpr self_t operator/(const self_t r) const { return { v / r.v }; }
// allow an unitless multiplier to scale the quantity: AU * f => AU
constexpr self_t operator*(const long double f) const { return { (T)(v * f) }; }
constexpr self_t operator/(const long double f) const { return { (T)(v / f) }; }
};
// complementary f * AU => AU * f
template <typename T, Axis A, config::UnitType U>
constexpr AxisUnit<T, A, U> operator*(const long double f, const AxisUnit<T, A, U> u) { return u * f; }
/// Axis type conversion table for template expansion
struct AxisScale {
unit::UnitBase base;

View File

@ -47,13 +47,22 @@ struct Unit {
typedef T type_t;
typedef Unit<T, B, U> self_t;
constexpr self_t operator+(const self_t r) { return { v + r.v }; }
constexpr self_t operator-(const self_t r) { return { v - r.v }; }
constexpr self_t operator-() { return { -v }; }
constexpr self_t operator*(const self_t r) { return { v * r.v }; }
constexpr self_t operator/(const self_t r) { return { v / r.v }; }
// same-type operations
constexpr self_t operator+(const self_t r) const { return { v + r.v }; }
constexpr self_t operator-(const self_t r) const { return { v - r.v }; }
constexpr self_t operator-() const { return { -v }; }
constexpr self_t operator*(const self_t r) const { return { v * r.v }; }
constexpr self_t operator/(const self_t r) const { return { v / r.v }; }
// allow an unitless multiplier to scale the quantity: U * f => U
constexpr self_t operator*(const long double f) const { return { (T)(v * f) }; }
constexpr self_t operator/(const long double f) const { return { (T)(v / f) }; }
};
// complementary f * U => U * f
template <typename T, UnitBase B, UnitType U>
constexpr Unit<T, B, U> operator*(const long double f, const Unit<T, B, U> u) { return u * f; }
// Millimiters
typedef Unit<long double, Millimeter, Lenght> U_mm;
typedef Unit<long double, Millimeter, Speed> U_mm_s;