diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c60f1e6..ce7bf7c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,12 +36,12 @@ conan_init(cmake) #enable_clang_tidy() #enable_iwyu() -# set restrictive compilation warnings -set_warnings(TREAT_AS_ERRORS) - # add project code add_subdirectory(src) +# set restrictive compilation warnings +set_warnings(units) + # add unit tests enable_testing() add_subdirectory(test) diff --git a/cmake/common b/cmake/common index f237ec11..eb5fbd40 160000 --- a/cmake/common +++ b/cmake/common @@ -1 +1 @@ -Subproject commit f237ec1139dc321a285a751a5a785b92efaaed28 +Subproject commit eb5fbd40d1cb765c5a8bf50866db86082c72ef73 diff --git a/example/avg_speed.cpp b/example/avg_speed.cpp index dcad8f5c..a0c4dbd1 100644 --- a/example/avg_speed.cpp +++ b/example/avg_speed.cpp @@ -114,8 +114,8 @@ void example() // Customary Units (double) { using namespace units::physical::international::literals; - constexpr Length AUTO distance = 140q_mi; // constructed from a UDL - constexpr si::time duration(2); // constructed from a value + constexpr Length AUTO distance = 140.q_mi; // constructed from a UDL + constexpr si::time duration(2); // constructed from a value std::cout << "\nUS Customary Units with 'double' as representation\n"; @@ -151,8 +151,8 @@ void example() // CGS (double) { using namespace units::physical::cgs::literals; - constexpr Length AUTO distance = 22'000'000q_cm; // constructed from a UDL - constexpr cgs::time duration(2); // constructed from a value + constexpr Length AUTO distance = 22'000'000.q_cm; // constructed from a UDL + constexpr cgs::time duration(2); // constructed from a value std::cout << "\nCGS units with 'double' as representation\n"; diff --git a/example/linear_algebra.cpp b/example/linear_algebra.cpp index 8bd69338..98ccf19b 100644 --- a/example/linear_algebra.cpp +++ b/example/linear_algebra.cpp @@ -93,7 +93,7 @@ void vector_of_quantity_multiply_same() std::cout << "u = " << u << "\n"; std::cout << "v * u = " << v * u << "\n"; - std::cout << "2q_m * v = " << 2q_m * v << "\n"; + std::cout << "2q_m * v = " << 2.q_m * v << "\n"; } void vector_of_quantity_multiply_different() @@ -107,7 +107,7 @@ void vector_of_quantity_multiply_different() std::cout << "u = " << u << "\n"; std::cout << "v * u = " << v * u << "\n"; - std::cout << "2q_N * u = " << 2q_N * u << "\n"; + std::cout << "2q_N * u = " << 2.q_N * u << "\n"; std::cout << "2 * u = " << 2 * u << "\n"; } @@ -162,7 +162,7 @@ void matrix_of_quantity_multiply_same() std::cout << "u =\n" << u << "\n"; std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2q_m * u =\n" << 2q_m * u << "\n"; + std::cout << "2q_m * u =\n" << 2.q_m * u << "\n"; } void matrix_of_quantity_multiply_different() @@ -176,7 +176,7 @@ void matrix_of_quantity_multiply_different() std::cout << "u =\n" << u << "\n"; std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2q_N * u =\n" << 2q_N * u << "\n"; + std::cout << "2q_N * u =\n" << 2.q_N * u << "\n"; std::cout << "2 * u =\n" << 2 * u << "\n"; } @@ -235,7 +235,7 @@ void quantity_of_vector_multiply_same() std::cout << "u = " << u << "\n"; std::cout << "v * u = " << v * u << "\n"; - std::cout << "2q_m * v = " << 2q_m * v << "\n"; + std::cout << "2q_m * v = " << 2.q_m * v << "\n"; } void quantity_of_vector_multiply_different() @@ -249,7 +249,7 @@ void quantity_of_vector_multiply_different() std::cout << "u = " << u << "\n"; std::cout << "v * u = " << v * u << "\n"; - std::cout << "2q_N * u = " << 2q_N * u << "\n"; + std::cout << "2q_N * u = " << 2.q_N * u << "\n"; std::cout << "2 * u = " << 2 * u << "\n"; } @@ -307,7 +307,7 @@ void quantity_of_matrix_multiply_same() std::cout << "u =\n" << u << "\n"; std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2q_m * u =\n" << 2q_m * u << "\n"; + std::cout << "2q_m * u =\n" << 2.q_m * u << "\n"; } void quantity_of_matrix_multiply_different() @@ -321,7 +321,7 @@ void quantity_of_matrix_multiply_different() std::cout << "u =\n" << u << "\n"; std::cout << "v * u =\n" << v * u << "\n"; - std::cout << "2q_N * u =\n" << 2q_N * u << "\n"; + std::cout << "2q_N * u =\n" << 2.q_N * u << "\n"; std::cout << "2 * u =\n" << 2 * u << "\n"; } diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index e497c8f1..e0a77d7e 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -346,9 +346,9 @@ template; if constexpr (treat_as_floating_point) { - return common_rep(lhs.count()) * common_rep(rhs.count()) * common_rep(ratio::num) * fpow10(ratio::exp) / common_rep(ratio::den); + return lhs.count() * rhs.count() * static_cast(ratio::num * fpow10(ratio::exp)) / static_cast(ratio::den); } else { - return common_rep(lhs.count()) * common_rep(rhs.count()) * common_rep(ratio::num) * ipow10(ratio::exp) / common_rep(ratio::den); + return lhs.count() * rhs.count() * static_cast(ratio::num * ipow10(ratio::exp)) / static_cast(ratio::den); } } diff --git a/src/include/units/quantity_cast.h b/src/include/units/quantity_cast.h index 7235ebb6..b0a7f77d 100644 --- a/src/include/units/quantity_cast.h +++ b/src/include/units/quantity_cast.h @@ -41,19 +41,19 @@ constexpr std::intmax_t ipow10(std::intmax_t exp) return result; } - -constexpr long double fpow10(std::intmax_t exp) +template +constexpr Rep fpow10(std::intmax_t exp) { - if (exp == 0) return 1.0L; - long double result = 1.0L; + if (exp == 0) return Rep(1.0); + Rep result = Rep(1.0); if (exp < 0) { while (exp < 0) { - result /= 10.0L; + result = result / Rep(10.0); ++exp; } } else { while (exp > 0) { - result *= 10.0L; + result = result * Rep(10.0); --exp; } } @@ -86,7 +86,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)))); + return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)))); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(static_cast(q.count()) * static_cast(ipow10(CRatio::exp)))); @@ -116,7 +116,7 @@ struct quantity_cast_impl { { if constexpr (treat_as_floating_point) { return To(static_cast(static_cast(q.count()) * - static_cast(fpow10(CRatio::exp)) * + static_cast(fpow10(CRatio::exp)) * (static_cast(CRatio::num) / static_cast(CRatio::den)))); } else { @@ -151,7 +151,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)) * (CRep{1} / static_cast(CRatio::den)))); + return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)) * (CRep{1} / static_cast(CRatio::den)))); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(static_cast(q.count()) * static_cast(ipow10(CRatio::exp)) / static_cast(CRatio::den))); @@ -178,7 +178,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) * static_cast(fpow10(CRatio::exp)))); + return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) * static_cast(fpow10(CRatio::exp)))); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) * static_cast(ipow10(CRatio::exp)))); @@ -196,7 +196,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(q.count() * fpow10(CRatio::exp))); + return To(static_cast(q.count() * fpow10(CRatio::exp))); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(q.count() * ipow10(CRatio::exp))); @@ -223,7 +223,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(q.count() * fpow10(CRatio::exp) * (CRatio::num / CRatio::den))); + return To(static_cast(q.count() * fpow10(CRatio::exp) * (CRatio::num / CRatio::den))); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(q.count() * CRatio::num * ipow10(CRatio::exp) / CRatio::den)); @@ -250,7 +250,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(q.count() * fpow10(CRatio::exp) / CRatio::den)); + return To(static_cast(q.count() * fpow10(CRatio::exp) / CRatio::den)); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(q.count() * ipow10(CRatio::exp) / CRatio::den)); @@ -277,7 +277,7 @@ struct quantity_cast_impl { static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { - return To(static_cast(q.count() * CRatio::num * fpow10(CRatio::exp))); + return To(static_cast(q.count() * CRatio::num * fpow10(CRatio::exp))); } else { if constexpr (CRatio::exp > 0) { return To(static_cast(q.count() * CRatio::num * ipow10(CRatio::exp))); diff --git a/test/unit_test/runtime/fmt_test.cpp b/test/unit_test/runtime/fmt_test.cpp index 4627b0ba..976ee8ce 100644 --- a/test/unit_test/runtime/fmt_test.cpp +++ b/test/unit_test/runtime/fmt_test.cpp @@ -448,7 +448,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("CGS base units") { - const auto q = 2q_s * cgs::length(2) * cgs::mass(2); + const auto q = 2.q_s * cgs::length(2) * cgs::mass(2); os << q; SECTION("iostream") @@ -533,7 +533,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]") SECTION("CGS base units") { - const auto q = 2q_s * cgs::length(2) * cgs::mass(2); + const auto q = 2.q_s * cgs::length(2) * cgs::mass(2); os << q; SECTION("iostream") diff --git a/test/unit_test/static/si_cgs_test.cpp b/test/unit_test/static/si_cgs_test.cpp index 87ca9a33..f828a691 100644 --- a/test/unit_test/static/si_cgs_test.cpp +++ b/test/unit_test/static/si_cgs_test.cpp @@ -130,8 +130,8 @@ static_assert(quantity_cast>(si::length( // static_assert(200q_cm * si::length(2) == si::area(4)); // should not compile (unknown dimension) -static_assert(quantity_cast(200q_cm) * si::length(2) == si::area(4)); -static_assert(200q_cm * quantity_cast(si::length(2)) == 40'000q_cm2); +static_assert(quantity_cast(200.q_cm) * si::length(2) == si::area(4)); +static_assert(200.q_cm * quantity_cast(si::length(2)) == 40'000q_cm2); // TODO Add support for quantity_cast on an unknown_dimension? // static_assert(quantity_cast>(200q_cm * si::length(2)) == si::area(4)); @@ -144,7 +144,7 @@ static_assert(200q_cm * quantity_cast(si::length(2)) // static_assert(si::area(4) / 200q_cm == si::length(2)); // should not compile (unknown dimension) static_assert(si::area(4) / quantity_cast>(200q_cm) == si::length(2)); -static_assert(quantity_cast>(si::area(4)) / 200q_cm == 200q_cm); +static_assert(quantity_cast>(si::area(4)) / 200.q_cm == 200q_cm); }