diff --git a/conanfile.py b/conanfile.py index 1ca432b6..dd08f782 100644 --- a/conanfile.py +++ b/conanfile.py @@ -47,7 +47,7 @@ class UnitsConan(ConanFile): settings = "compiler", "build_type" requires = ( "fmt/7.0.3", - "ms-gsl/3.1.0" + "gsl-lite/0.37.0" ) options = { "downcast_mode": ["off", "on", "auto"], @@ -135,7 +135,7 @@ class UnitsConan(ConanFile): self.cpp_info.names["cmake_find_package"] = "mp" self.cpp_info.names["cmake_find_package_multi"] = "mp" self.cpp_info.components["units"].name = "units" - self.cpp_info.components["units"].requires = ["fmt::fmt", "ms-gsl::ms-gsl"] + self.cpp_info.components["units"].requires = ["fmt::fmt", "gsl::gsl-lite"] compiler = self.settings.compiler version = Version(self.settings.compiler.version) diff --git a/docs/usage.rst b/docs/usage.rst index ca034f91..47690188 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -18,7 +18,7 @@ This repository contains three independent CMake-based projects: but until then it depends on: - `{fmt} `_ to provide text formatting of quantities. - - `ms-gsl `_ to verify runtime contracts with ``Expects`` macro. + - `gsl-lite `_ to verify runtime contracts with ``Expects`` macro. - *.* diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eabb140d..74f20975 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ set_property(CACHE UNITS_DOWNCAST_MODE PROPERTY STRINGS AUTO ON OFF) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") find_package(fmt CONFIG REQUIRED) -find_package(Microsoft.GSL CONFIG REQUIRED) +find_package(gsl-lite CONFIG REQUIRED) # library definition add_library(mp-units INTERFACE) @@ -42,7 +42,7 @@ target_compile_features(mp-units INTERFACE cxx_std_20) target_link_libraries(mp-units INTERFACE fmt::fmt - Microsoft.GSL::GSL + gsl::gsl-lite ) target_include_directories(mp-units INTERFACE diff --git a/src/include/units/bits/constexpr_math.h b/src/include/units/bits/constexpr_math.h index 53e4fdf4..d57ec497 100644 --- a/src/include/units/bits/constexpr_math.h +++ b/src/include/units/bits/constexpr_math.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include @@ -65,7 +65,7 @@ struct decimal_fp { */ [[nodiscard]] constexpr double constexpr_log(double v) noexcept { - Expects(v > 0); + gsl_Expects(v > 0); // lookup table to speed up convergence for all significant values // significant values of 7 and greater benefit mostly as they now converge in 5 terms compared to O(10)-O(100) diff --git a/src/include/units/bits/ratio_maths.h b/src/include/units/bits/ratio_maths.h index 31a188e7..a679c6bb 100644 --- a/src/include/units/bits/ratio_maths.h +++ b/src/include/units/bits/ratio_maths.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include namespace units::detail { @@ -183,10 +183,10 @@ constexpr void normalize(std::intmax_t& num, std::intmax_t& den, std::intmax_t& const std::intmax_t b0 = detail::abs(rhs) % c; const std::intmax_t b1 = detail::abs(rhs) / c; - Expects(a1 == 0 || b1 == 0); // overflow in multiplication - Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication - Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication - Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication + gsl_Expects(a1 == 0 || b1 == 0); // overflow in multiplication + gsl_Expects(a0 * b1 + b0 * a1 < (c >> 1)); // overflow in multiplication + gsl_Expects(b0 * a0 <= INTMAX_MAX); // overflow in multiplication + gsl_Expects((a0 * b1 + b0 * a1) * c <= INTMAX_MAX - b0 * a0); // overflow in multiplication return lhs * rhs; } diff --git a/src/include/units/bits/root.h b/src/include/units/bits/root.h index 6ae24383..e718ef8a 100644 --- a/src/include/units/bits/root.h +++ b/src/include/units/bits/root.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #include #include #include @@ -38,7 +38,7 @@ template if constexpr (N == 1) { return v; } else { - Expects(v >= 0); + gsl_Expects(v >= 0); if (v == 0) { return 0; } diff --git a/src/include/units/one_rep.h b/src/include/units/one_rep.h index 18d19df3..4e2573b9 100644 --- a/src/include/units/one_rep.h +++ b/src/include/units/one_rep.h @@ -28,6 +28,8 @@ namespace units { +struct invalid_one_rep {}; + /** * @brief A representation type to be used for unit constants * @@ -88,11 +90,22 @@ struct one_rep { [[nodiscard]] bool operator==(const one_rep&) const = default; [[nodiscard]] auto operator<=>(const one_rep&) const = default; + + [[nodiscard]] constexpr bool operator==(const invalid_one_rep&) const { return false; } +}; + +template<> +struct quantity_values { + static constexpr invalid_one_rep zero() noexcept { return invalid_one_rep{}; } + static constexpr one_rep one() noexcept { return one_rep{}; } + static constexpr one_rep min() noexcept { return one(); } + static constexpr one_rep max() noexcept { return one(); } }; } // namespace units namespace std { + template<> struct common_type { using type = units::one_rep; diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index a3b91944..ffc05be5 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -270,7 +270,7 @@ public: invoke_result_convertible_to_, rep, const Value&> [[nodiscard]] friend constexpr Quantity auto operator/(const quantity& q, const Value& v) { - // Expects(v != zero().count()); + gsl_ExpectsAudit(v != quantity_values::zero()); using ret = quantity, rep, Value>>; return ret(q.count() / v); } @@ -280,7 +280,7 @@ public: invoke_result_convertible_to_, const Value&, rep> [[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q) { - // Expects(q.count() != zero().count()); + gsl_ExpectsAudit(q.count() != quantity_values::zero()); using dim = dim_invert; using ret_unit = downcast_unit; using ret = quantity, Value, rep>>; @@ -354,7 +354,7 @@ template, Rep1, Rep2> [[nodiscard]] constexpr Quantity auto operator/(const quantity& lhs, const quantity& rhs) { - // Expects(rhs.count() != zero().count()); + gsl_ExpectsAudit(rhs.count() != (quantity_values::zero())); using dim = dimension_divide; using unit = downcast_unit::ratio) / (U2::ratio / dimension_unit::ratio) * dimension_unit::ratio>; using ret = quantity, Rep1, Rep2>>; diff --git a/src/include/units/ratio.h b/src/include/units/ratio.h index 2af76f9b..7b1ea90b 100644 --- a/src/include/units/ratio.h +++ b/src/include/units/ratio.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include namespace units { @@ -53,7 +53,7 @@ struct ratio { explicit constexpr ratio(std::intmax_t n, std::intmax_t d = 1, std::intmax_t e = 0): num(n), den(d), exp(e) { - Expects(den != 0); + gsl_Expects(den != 0); detail::normalize(num, den, exp); } @@ -92,7 +92,7 @@ namespace detail { [[nodiscard]] constexpr auto make_exp_align(const ratio& r, std::intmax_t alignment) { - Expects(alignment > 0); + gsl_Expects(alignment > 0); const std::intmax_t rem = r.exp % alignment; if (rem == 0) { // already aligned diff --git a/src/include/units/symbol_text.h b/src/include/units/symbol_text.h index f38ee6f2..2b774de3 100644 --- a/src/include/units/symbol_text.h +++ b/src/include/units/symbol_text.h @@ -24,14 +24,14 @@ #include #include -#include +#include #include namespace units { namespace detail { -constexpr void validate_ascii_char([[maybe_unused]] char c) noexcept { Expects((c & 0x80) == 0); } +constexpr void validate_ascii_char([[maybe_unused]] char c) noexcept { gsl_Expects((c & 0x80) == 0); } template constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[N + 1]) noexcept diff --git a/src/mp-unitsConfig.cmake b/src/mp-unitsConfig.cmake index e9ad2a72..9dcca1ab 100644 --- a/src/mp-unitsConfig.cmake +++ b/src/mp-unitsConfig.cmake @@ -22,6 +22,6 @@ include(CMakeFindDependencyMacro) find_dependency(fmt) -find_dependency(Microsoft.GSL) +find_dependency(gsl-lite) include("${CMAKE_CURRENT_LIST_DIR}/mp-unitsTargets.cmake")