diff --git a/openVulkanoCpp/Base/UnitFormatter.cpp b/openVulkanoCpp/Base/UnitFormatter.cpp index 55de4ee..b0a4e1b 100644 --- a/openVulkanoCpp/Base/UnitFormatter.cpp +++ b/openVulkanoCpp/Base/UnitFormatter.cpp @@ -11,36 +11,61 @@ namespace { - template static std::string formatValue(T value, int precision) + template std::string FormatValue(T value, int precision, bool trimTrailingZeros = false) { - std::ostringstream stream; - stream << std::fixed << std::setprecision(precision) << value; - return stream.str(); + std::ostringstream out; + out << std::fixed << std::setprecision(precision) << value; + std::string result = out.str(); + + if (trimTrailingZeros && result.find('.') != std::string::npos) + { + result.erase(result.find_last_not_of('0') + 1); + + if (result.back() == '.') + { + result.pop_back(); + } + } + + return result; } } namespace OpenVulkano { - UnitFormatter::UnitFormatter(bool useMetric, int precisionDigits) : metric(useMetric), precision(precisionDigits) {} + UnitFormatter::UnitFormatter(bool useMetric, int precisionDigits, bool doTrimTrailingZeros) + : metric(useMetric), precision(precisionDigits), trimTrailingZeros(doTrimTrailingZeros) + { + } std::string UnitFormatter::Format(units::length::meter_t distance) { if (metric) { - if (distance >= units::length::kilometer_t(1)) + if (distance > units::length::meter_t(0) && distance < units::length::meter_t(0.1)) { - return formatValue(units::length::kilometer_t(distance).value(), precision) + " km"; + return FormatValue(units::length::millimeter_t(distance).value(), precision, trimTrailingZeros) + " mm"; } - return formatValue(distance.value(), precision) + " m"; + else if (distance >= units::length::kilometer_t(1)) + { + return FormatValue(units::length::kilometer_t(distance).value(), precision, trimTrailingZeros) + " km"; + } + return FormatValue(distance.value(), precision, trimTrailingZeros) + " m"; } else { auto distanceFeet = units::length::foot_t(distance).value(); - if (distanceFeet >= 5280.0) + auto distanceInches = units::length::inch_t(distance).value(); + + if (distanceFeet > 0 && distanceFeet < 0.1) { - return formatValue(units::length::mile_t(distance).value(), precision) + " mi"; + return FormatValue(distanceInches, precision, trimTrailingZeros) + " in"; } - return formatValue(distanceFeet, precision) + " ft"; + else if (distanceFeet >= 5280.0) + { + return FormatValue(units::length::mile_t(distance).value(), precision, trimTrailingZeros) + " mi"; + } + return FormatValue(distanceFeet, precision, trimTrailingZeros) + " ft"; } } @@ -50,18 +75,19 @@ namespace OpenVulkano { if (area >= units::area::square_kilometer_t(1)) { - return formatValue(units::area::square_kilometer_t(area).value(), precision) + " km²"; + return FormatValue(units::area::square_kilometer_t(area).value(), precision, trimTrailingZeros) + + " km²"; } - return formatValue(area.value(), precision) + " m²"; + return FormatValue(area.value(), precision, trimTrailingZeros) + " m²"; } else { auto areaSquareFeet = units::area::square_foot_t(area).value(); if (areaSquareFeet >= 27878400.0) { - return formatValue(units::area::square_mile_t(area).value(), precision) + " mi²"; + return FormatValue(units::area::square_mile_t(area).value(), precision, trimTrailingZeros) + " mi²"; } - return formatValue(areaSquareFeet, precision) + " ft²"; + return FormatValue(areaSquareFeet, precision, trimTrailingZeros) + " ft²"; } } } \ No newline at end of file diff --git a/openVulkanoCpp/Base/UnitFormatter.hpp b/openVulkanoCpp/Base/UnitFormatter.hpp index 4d59107..ebfd8ea 100644 --- a/openVulkanoCpp/Base/UnitFormatter.hpp +++ b/openVulkanoCpp/Base/UnitFormatter.hpp @@ -14,9 +14,10 @@ namespace OpenVulkano { bool metric = true; int precision = 3; + bool trimTrailingZeros = true; public: - UnitFormatter(bool useMetric = true, int precisionDigits = 3); + UnitFormatter(bool useMetric = true, int precisionDigits = 3, bool doTrimTrailingZeros = true); std::string Format(units::length::meter_t distance); std::string Format(units::area::square_meter_t area); }; diff --git a/tests/UnitFormatter.cpp b/tests/UnitFormatter.cpp index b7f9416..8f2d2b3 100644 --- a/tests/UnitFormatter.cpp +++ b/tests/UnitFormatter.cpp @@ -10,14 +10,16 @@ using namespace units::literals; -TEST_CASE("testUnitFormatter", "[UnitFormatter]") +TEST_CASE("testUnitFormatterWithTrailingZeros", "[UnitFormatter]") { - OpenVulkano::UnitFormatter metricFormatter(true, 2); - OpenVulkano::UnitFormatter imperialFormatter(false, 2); + OpenVulkano::UnitFormatter metricFormatter(true, 2, false); + OpenVulkano::UnitFormatter imperialFormatter(false, 2, false); units::length::meter_t positiveDistance = 1500.0_m; units::length::meter_t smallDistance = 0.5_m; units::length::meter_t negativeDistance = -100.0_m; + units::length::meter_t smallDistanceMetric = 0.05_m; + units::length::meter_t smallDistanceImperial = 0.03_m; units::area::square_meter_t smallArea(0.005); units::area::square_meter_t negativeArea(-50.0); @@ -30,4 +32,37 @@ TEST_CASE("testUnitFormatter", "[UnitFormatter]") REQUIRE(imperialFormatter.Format(negativeDistance) == "-328.08 ft"); REQUIRE(imperialFormatter.Format(smallArea) == "0.05 ft²"); REQUIRE(imperialFormatter.Format(negativeArea) == "-538.20 ft²"); + REQUIRE(metricFormatter.Format(smallDistanceMetric) == "50.00 mm"); + REQUIRE(imperialFormatter.Format(smallDistanceImperial) == "1.18 in"); } + +TEST_CASE("testUnitFormatterWithoutTrailingZeros", "[UnitFormatter]") +{ + OpenVulkano::UnitFormatter metricFormatter(true, 2); + OpenVulkano::UnitFormatter imperialFormatter(false, 2); + + units::length::meter_t positiveDistance = 1500.0_m; + units::length::meter_t smallDistance = 0.5_m; + units::length::meter_t negativeDistance = -100.0_m; + units::length::meter_t smallDistanceMetric = 0.05_m; + units::length::meter_t smallDistanceImperial = 0.03_m; + units::length::meter_t mediumDistanceMetric = 0.5_m; + units::length::meter_t largeDistanceMetric = 100.0_m; + units::area::square_meter_t smallArea(0.005); + units::area::square_meter_t negativeArea(-50.0); + + REQUIRE(metricFormatter.Format(positiveDistance) == "1.5 km"); + REQUIRE(metricFormatter.Format(smallDistance) == "0.5 m"); + REQUIRE(metricFormatter.Format(negativeDistance) == "-100 m"); + REQUIRE(metricFormatter.Format(smallArea) == "0.01 m²"); + REQUIRE(metricFormatter.Format(negativeArea) == "-50 m²"); + REQUIRE(imperialFormatter.Format(smallDistance) == "1.64 ft"); + REQUIRE(imperialFormatter.Format(negativeDistance) == "-328.08 ft"); + REQUIRE(imperialFormatter.Format(smallArea) == "0.05 ft²"); + REQUIRE(imperialFormatter.Format(negativeArea) == "-538.2 ft²"); + REQUIRE(metricFormatter.Format(smallDistanceMetric) == "50 mm"); + REQUIRE(imperialFormatter.Format(smallDistanceImperial) == "1.18 in"); + REQUIRE(metricFormatter.Format(smallDistanceMetric) == "50 mm"); + REQUIRE(metricFormatter.Format(mediumDistanceMetric) == "0.5 m"); + REQUIRE(metricFormatter.Format(largeDistanceMetric) == "100 m"); +} \ No newline at end of file