From 0515c4d4fb104954451fe9f57efd93ee8c911827 Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Tue, 7 Jan 2025 14:07:13 -0800 Subject: [PATCH 1/5] add format support to normal units --- include/units/units.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/units/units.hpp b/include/units/units.hpp index 7e67bc3..ea27459 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -7,6 +7,7 @@ #include #include #include +#include // define M_PI if not already defined #ifndef M_PI @@ -313,6 +314,11 @@ template constexpr bool operator>(const Q& lhs, con return Name(Quantity, std::ratio, std::ratio, std::ratio, std::ratio, std::ratio, \ std::ratio, std::ratio>(static_cast(value))); \ } \ + template <> struct std::formatter : std::formatter { \ + auto format(const Name& quantity, std::format_context& ctx) const { \ + return std::format_to(ctx.out(), "{}_##suffix", quantity.internal()); \ + } \ + }; \ inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ os << quantity.internal() << " " << #suffix; \ return os; \ @@ -355,6 +361,12 @@ constexpr Number operator""_num(unsigned long long value) { std::ratio<0>, std::ratio<0>>(static_cast(value))); } +template <> struct std::formatter : std::formatter { + auto format(const Number& quantity, std::format_context& ctx) const { + return std::format_to(ctx.out(), "{}", quantity.internal()); + } +}; + inline std::ostream& operator<<(std::ostream& os, const Number& quantity) { os << quantity.internal() << " " << num; return os; From f802474514fa9c8d8c982ede8371dd18a25da3fc Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Tue, 7 Jan 2025 15:25:45 -0800 Subject: [PATCH 2/5] add std::format support to units, Temperature, and Angle --- include/units/Angle.hpp | 7 +++++++ include/units/Temperature.hpp | 6 ++++++ include/units/units.hpp | 34 ++++++++++++++++++++-------------- src/main.cpp | 25 +++++++++++++++++-------- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/include/units/Angle.hpp b/include/units/Angle.hpp index ca3190c..4ad448f 100644 --- a/include/units/Angle.hpp +++ b/include/units/Angle.hpp @@ -21,6 +21,13 @@ template <> struct LookupName, std::ratio<0>, std::ratio< using Named = Angle; }; +template <> struct std::formatter : std::formatter { + auto format(const Angle& number, std::format_context& ctx) const { + auto formatted_double = std::formatter::format(number.internal(), ctx); + return std::format_to(formatted_double, "_stRad"); + } +}; + inline std::ostream& operator<<(std::ostream& os, const Angle& quantity) { os << quantity.internal() << " rad"; return os; diff --git a/include/units/Temperature.hpp b/include/units/Temperature.hpp index faf1070..976ecb1 100644 --- a/include/units/Temperature.hpp +++ b/include/units/Temperature.hpp @@ -21,6 +21,12 @@ template <> struct LookupName, std::ratio<0>, std::ratio< using Named = Temperature; }; +template <> struct std::formatter : std::formatter { + auto format(const Temperature& quantity, std::format_context& ctx) const { + return std::format_to(ctx.out(), "{}_k", quantity.internal()); + } +}; + inline std::ostream& operator<<(std::ostream& os, const Temperature& quantity) { os << quantity.internal() << " k"; return os; diff --git a/include/units/units.hpp b/include/units/units.hpp index ea27459..f34cddb 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -315,8 +315,9 @@ template constexpr bool operator>(const Q& lhs, con std::ratio, std::ratio>(static_cast(value))); \ } \ template <> struct std::formatter : std::formatter { \ - auto format(const Name& quantity, std::format_context& ctx) const { \ - return std::format_to(ctx.out(), "{}_##suffix", quantity.internal()); \ + auto format(const Name& number, std::format_context& ctx) const { \ + auto formatted_double = std::formatter::format(number.internal(), ctx); \ + return std::format_to(formatted_double, "_" #suffix); \ } \ }; \ inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ @@ -610,12 +611,14 @@ template constexpr Q round(const Q& lhs, const R& r // Convert an angular unit `Q` to a linear unit correctly; // mostly useful for velocities -template Quantity -toLinear(Quantity - angular, - Length diameter) { +template +Quantity constexpr toLinear(Quantity + angular, + Length diameter) { return unit_cast>( angular * (diameter / 2.0)); @@ -623,12 +626,15 @@ toLinear(Quantity Quantity -toAngular(Quantity - linear, - Length diameter) { +template +Quantity constexpr toAngular(Quantity + linear, + Length diameter) { return unit_cast>( linear / (diameter / 2.0)); diff --git a/src/main.cpp b/src/main.cpp index 7176cc5..31bbafd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,13 +6,14 @@ constexpr int r2i(double value) { return static_cast(value >= 0.0 ? value + 0.5 : value - 0.5); } -/** - * Runs initialization code. This occurs as soon as the program is started. - * - * All other competition modes are blocked by initialize; it is recommended - * to keep execution time for this mode under a few seconds. - */ void initialize() { + std::cout << std::format("{:.2f}", 15.2_cm) << std::endl; // should output 0.15_m + std::cout << std::format("{:.2f}", 180_stDeg) << std::endl; // should output 3.14_stRad + std::cout << std::format("{:.2f}", 0_celsius) << std::endl; // should output 273.15 + std::cout << std::format("{:.2f}", 1.2345) << std::endl; +} + +constexpr void miscTests() { units::AccelerationPose a(1_mps2, 2_mps2); Number num = Number(1.0); num = Number(0.0); @@ -30,12 +31,18 @@ void initialize() { std::ratio<0>, std::ratio<0>, std::ratio<0>>(5.0)); units::max(10_celsius, Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>, std::ratio<0>, std::ratio<0>>(1.0)); +} + +constexpr void v3dTests() { // check Vector3D overloads units::Vector3D v3a = 2 * units::V3Position(2_in, 2_in, 2_in) * 2; units::Vector3D v3b = units::V3Position(2_in, 2_in, 2_in) / 2.0; units::Vector3D v3c = 2_in * units::V3Position(2_in, 2_in, 2_in); units::Vector3D v3d = units::V3Position(2_in, 2_in, 2_in) * 2_in; units::Vector3D v3e = units::V3Position(2_in, 2_in, 2_in) / 2_in; +} + +constexpr void v2dTests() { // check Vector2D overloads units::Vector2D v2a = units::V2Position(2_in, 2_in) / 2; units::Vector2D v2b = 2 * units::V2Position(2_in, 2_in) * 2; @@ -81,7 +88,7 @@ constexpr double doubleAssignmentTests() { return d; } -void numberOperatorTests() { +constexpr void numberOperatorTests() { using namespace units_double_ops; static_assert(1_num + 2 == 3); static_assert(1 + 2_num <= 3); @@ -89,4 +96,6 @@ void numberOperatorTests() { static_assert(numAssignmentTests() == 0); static_assert(doubleAssignmentTests() == 1); -} \ No newline at end of file +} + +constexpr void formatTests() {} \ No newline at end of file From 05fac66e79c3ccb3b1bb665f5e3cc1d5c8730bec Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Tue, 7 Jan 2025 16:38:52 -0800 Subject: [PATCH 3/5] add std::format support for unnamed types --- include/units/units.hpp | 43 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 2 ++ 2 files changed, 45 insertions(+) diff --git a/include/units/units.hpp b/include/units/units.hpp index f34cddb..16fa5b0 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -184,6 +184,49 @@ template using Rooted = Named< std::ratio_divide, std::ratio_divide, std::ratio_divide, std::ratio_divide>>; +template + requires(!std::is_same_v, Q>) +struct std::formatter : std::formatter { + auto format(const Q& quantity, std::format_context& ctx) const { + // return std::format_to(ctx.out(), "{}", quantity.internal()); + return std::formatter>::format(quantity, ctx); + } +}; + +template + requires std::is_same_v, Q> +struct std::formatter : std::formatter { + auto format(const Q& quantity, std::format_context& ctx) const { + constinit static std::array, 8> dims {{ + {Q::mass::num, Q::mass::den}, + {Q::length::num, Q::length::den}, + {Q::time::num, Q::time::den}, + {Q::current::num, Q::current::den}, + {Q::angle::num, Q::angle::den}, + {Q::temperature::num, Q::temperature::den}, + {Q::luminosity::num, Q::luminosity::den}, + {Q::moles::num, Q::moles::den}, + }}; + std::array prefixes {"_kg", "_m", "_s", "_A", "_rad", "_K", "_cd", "_mol"}; + + auto out = ctx.out(); + + // Format the quantity value + out = std::formatter::format(quantity.internal(), ctx); + + // Add dimensions and prefixes + for (size_t i = 0; i != 8; i++) { + if (dims[i].first != 0) { + out = std::format_to(out, "{}", prefixes[i]); + if (dims[i].first != 1 || dims[i].second != 1) { out = std::format_to(out, "^{}", dims[i].first); } + if (dims[i].second != 1) { out = std::format_to(out, "/{}", dims[i].second); } + } + } + + return out; + } +}; + inline void unit_printer_helper(std::ostream& os, double quantity, const std::array, 8>& dims) { static constinit std::array prefixes {"_kg", "_m", "_s", "_A", "_rad", "_K", "_cd", "_mol"}; diff --git a/src/main.cpp b/src/main.cpp index 31bbafd..fddaa4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,8 @@ void initialize() { std::cout << std::format("{:.2f}", 180_stDeg) << std::endl; // should output 3.14_stRad std::cout << std::format("{:.2f}", 0_celsius) << std::endl; // should output 273.15 std::cout << std::format("{:.2f}", 1.2345) << std::endl; + std::cout << units::pow<5>(505_cm) * 15_celsius << std::endl; + std::cout << std::format("{:.2f}", units::pow<5>(505_cm) * 15_celsius) << std::endl; } constexpr void miscTests() { From c9b95c0d8c948d86cbebe7b3f800fceb261e042a Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Tue, 7 Jan 2025 16:54:16 -0800 Subject: [PATCH 4/5] support unnamed units properly --- include/units/units.hpp | 17 +++-------------- src/main.cpp | 2 ++ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/include/units/units.hpp b/include/units/units.hpp index 16fa5b0..381b99f 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -184,18 +184,7 @@ template using Rooted = Named< std::ratio_divide, std::ratio_divide, std::ratio_divide, std::ratio_divide>>; -template - requires(!std::is_same_v, Q>) -struct std::formatter : std::formatter { - auto format(const Q& quantity, std::format_context& ctx) const { - // return std::format_to(ctx.out(), "{}", quantity.internal()); - return std::formatter>::format(quantity, ctx); - } -}; - -template - requires std::is_same_v, Q> -struct std::formatter : std::formatter { +template struct std::formatter : std::formatter { auto format(const Q& quantity, std::format_context& ctx) const { constinit static std::array, 8> dims {{ {Q::mass::num, Q::mass::den}, @@ -406,8 +395,8 @@ constexpr Number operator""_num(unsigned long long value) { } template <> struct std::formatter : std::formatter { - auto format(const Number& quantity, std::format_context& ctx) const { - return std::format_to(ctx.out(), "{}", quantity.internal()); + auto format(const Number& number, std::format_context& ctx) const { + return std::formatter::format(number.internal(), ctx); } }; diff --git a/src/main.cpp b/src/main.cpp index fddaa4f..b0217fe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,8 @@ void initialize() { std::cout << std::format("{:.2f}", 1.2345) << std::endl; std::cout << units::pow<5>(505_cm) * 15_celsius << std::endl; std::cout << std::format("{:.2f}", units::pow<5>(505_cm) * 15_celsius) << std::endl; + Number a(2.123); + std::cout << std::format("{:.2f}", a) << std::endl; } constexpr void miscTests() { From dc8f67f0e2c5cf24b6d078c2304f8d4a00ccfc64 Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Tue, 7 Jan 2025 16:57:48 -0800 Subject: [PATCH 5/5] update pros-build --- .github/workflows/pros-build.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pros-build.yml b/.github/workflows/pros-build.yml index 6deec5c..b9634cc 100644 --- a/.github/workflows/pros-build.yml +++ b/.github/workflows/pros-build.yml @@ -1,4 +1,4 @@ -name: Build Template +name: PROS Build Template on: push: @@ -16,14 +16,11 @@ jobs: uses: actions/checkout@v4 - name: Run LemLib/pros-build - id: build-template - uses: LemLib/pros-build@v2.0.1 - with: - copy_readme_and_license_to_include: true - lib_folder_name: units + id: test + uses: LemLib/pros-build@v4.0.0 - name: Upload Artifact uses: actions/upload-artifact@v4 with: - name: ${{ steps.build-template.outputs.name }} + name: ${{ steps.test.outputs.name }} path: ${{ github.workspace }}/template/* \ No newline at end of file