From 7dcd4975e197d13cd0c2a64024f88011ec66bd24 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Fri, 30 Jul 2021 00:51:51 +0200 Subject: [PATCH] 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) --- src/modules/axisunit.h | 19 ++++++++++++++----- src/unit.h | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/modules/axisunit.h b/src/modules/axisunit.h index fbe91e4..5c3a340 100644 --- a/src/modules/axisunit.h +++ b/src/modules/axisunit.h @@ -73,13 +73,22 @@ struct AxisUnit { typedef T type_t; typedef AxisUnit 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 +constexpr AxisUnit operator*(const long double f, const AxisUnit u) { return u * f; } + /// Axis type conversion table for template expansion struct AxisScale { unit::UnitBase base; diff --git a/src/unit.h b/src/unit.h index 9364d08..38e3405 100644 --- a/src/unit.h +++ b/src/unit.h @@ -47,13 +47,22 @@ struct Unit { typedef T type_t; typedef Unit 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 +constexpr Unit operator*(const long double f, const Unit u) { return u * f; } + // Millimiters typedef Unit U_mm; typedef Unit U_mm_s;