diff --git a/CMakeLists.txt b/CMakeLists.txt index c46ed21c9..8e1e02045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,7 +182,7 @@ enable_testing() find_program(${PROJECT_NAME}_MEMORY_CHECK_COMMAND valgrind) set(${PROJECT_NAME}_MEMORY_CHECK_OPTIONS - --error-exitcode=1 # = EXIT_FAILURE) + --error-exitcode=1 # = EXIT_FAILURE --leak-check=full --quiet --show-leak-kinds=all) diff --git a/README.md b/README.md index 670026675..dc89c7f1c 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Procedures for each standard are provided by the following R7RS-style libraries: cmake -B build -DCMAKE_BUILD_TYPE=Release cd build make package -sudo apt install build/meevax_0.5.228_amd64.deb +sudo apt install build/meevax_0.5.229_amd64.deb ``` or @@ -122,9 +122,9 @@ sudo rm -rf /usr/local/share/meevax | Target Name | Description |-------------|------------- -| `all` | Build shared-library `libmeevax.0.5.228.so` and executable `meevax` +| `all` | Build shared-library `libmeevax.0.5.229.so` and executable `meevax` | `test` | Test executable `meevax` -| `package` | Generate debian package `meevax_0.5.228_amd64.deb` +| `package` | Generate debian package `meevax_0.5.229_amd64.deb` | `install` | Copy files into `/usr/local` directly ## Usage diff --git a/VERSION b/VERSION index 6e3ecf4f9..06fbeca31 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.228 +0.5.229 diff --git a/include/meevax/kernel/exact_integer.hpp b/include/meevax/kernel/exact_integer.hpp index 3d2dff835..d56431ffa 100644 --- a/include/meevax/kernel/exact_integer.hpp +++ b/include/meevax/kernel/exact_integer.hpp @@ -39,23 +39,22 @@ inline namespace kernel explicit exact_integer(mpz_t const) noexcept; - explicit exact_integer(std::int8_t); - - explicit exact_integer(std::int16_t); - - explicit exact_integer(std::int32_t); - - explicit exact_integer(std::int64_t); - - explicit exact_integer(std::uint8_t); - - explicit exact_integer(std::uint16_t); - - explicit exact_integer(std::uint32_t); - - explicit exact_integer(std::uint64_t); - - explicit exact_integer(double); + template >> + explicit exact_integer(T x) + { + if constexpr (std::is_floating_point_v) + { + mpz_init_set_d(value, x); + } + else if constexpr (std::is_signed_v) + { + mpz_init_set_si(value, x); + } + else + { + mpz_init_set_ui(value, x); + } + } explicit exact_integer(std::string const&, int = 0); @@ -67,49 +66,50 @@ inline namespace kernel explicit operator bool() const; - operator std::int8_t() const; - - operator std::int16_t() const; - - operator std::int32_t() const; - - operator std::int64_t() const; - - operator std::uint8_t() const; - - operator std::uint16_t() const; - - operator std::uint32_t() const; - - operator std::uint64_t() const; - - explicit operator float() const; - - explicit operator double() const; + template >> + operator T() const + { + if constexpr (std::is_floating_point_v) + { + return mpz_get_d(value); + } + else if constexpr (std::is_signed_v) + { + return mpz_get_si(value); + } + else + { + return mpz_get_ui(value); + } + } auto square_root() const -> std::tuple; }; - auto operator ==(exact_integer const&, int const) -> bool; - auto operator !=(exact_integer const&, int const) -> bool; - auto operator < (exact_integer const&, int const) -> bool; - auto operator <=(exact_integer const&, int const) -> bool; - auto operator > (exact_integer const&, int const) -> bool; - auto operator >=(exact_integer const&, int const) -> bool; - - auto operator ==(exact_integer const&, signed long const) -> bool; - auto operator !=(exact_integer const&, signed long const) -> bool; - auto operator < (exact_integer const&, signed long const) -> bool; - auto operator <=(exact_integer const&, signed long const) -> bool; - auto operator > (exact_integer const&, signed long const) -> bool; - auto operator >=(exact_integer const&, signed long const) -> bool; - - auto operator ==(exact_integer const&, unsigned long const) -> bool; - auto operator !=(exact_integer const&, unsigned long const) -> bool; - auto operator < (exact_integer const&, unsigned long const) -> bool; - auto operator <=(exact_integer const&, unsigned long const) -> bool; - auto operator > (exact_integer const&, unsigned long const) -> bool; - auto operator >=(exact_integer const&, unsigned long const) -> bool; + #define DEFINE_COMPARISON_OPERATOR(SYMBOL) \ + template >> \ + auto operator SYMBOL(exact_integer const& a, T b) \ + { \ + if constexpr (std::is_floating_point_v) \ + { \ + return mpz_cmp_d(a.value, b) SYMBOL 0; \ + } \ + else if constexpr (std::is_signed_v) \ + { \ + return mpz_cmp_si(a.value, b) SYMBOL 0; \ + } \ + else \ + { \ + return mpz_cmp_ui(a.value, b) SYMBOL 0; \ + } \ + } static_assert(true) + + DEFINE_COMPARISON_OPERATOR(==); + DEFINE_COMPARISON_OPERATOR(!=); + DEFINE_COMPARISON_OPERATOR(< ); + DEFINE_COMPARISON_OPERATOR(<=); + DEFINE_COMPARISON_OPERATOR(> ); + DEFINE_COMPARISON_OPERATOR(>=); auto operator <<(std::ostream &, exact_integer const&) -> std::ostream &; diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 3c498d050..527f8084e 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -53,51 +53,6 @@ inline namespace kernel mpz_init_set(value, z); } - exact_integer::exact_integer(std::int8_t si) - { - mpz_init_set_si(value, si); - } - - exact_integer::exact_integer(std::int16_t si) - { - mpz_init_set_si(value, si); - } - - exact_integer::exact_integer(std::int32_t si) - { - mpz_init_set_si(value, si); - } - - exact_integer::exact_integer(std::int64_t si) - { - mpz_init_set_si(value, si); - } - - exact_integer::exact_integer(std::uint8_t ui) - { - mpz_init_set_ui(value, ui); - } - - exact_integer::exact_integer(std::uint16_t ui) - { - mpz_init_set_ui(value, ui); - } - - exact_integer::exact_integer(std::uint32_t ui) - { - mpz_init_set_ui(value, ui); - } - - exact_integer::exact_integer(std::uint64_t ui) - { - mpz_init_set_ui(value, ui); - } - - exact_integer::exact_integer(double d) - { - mpz_init_set_d(value, d); - } - exact_integer::exact_integer(std::string const& s, int radix) { if (mpz_init_set_str(value, (s.at(0) == '+' ? s.substr(1) : s).c_str(), radix)) @@ -136,56 +91,6 @@ inline namespace kernel return (*value)._mp_size; } - exact_integer::operator std::int8_t() const - { - return mpz_get_si(value); - } - - exact_integer::operator std::int16_t() const - { - return mpz_get_si(value); - } - - exact_integer::operator std::int32_t() const - { - return mpz_get_si(value); - } - - exact_integer::operator std::int64_t() const - { - return mpz_get_si(value); - } - - exact_integer::operator std::uint8_t() const - { - return mpz_get_ui(value); - } - - exact_integer::operator std::uint16_t() const - { - return mpz_get_ui(value); - } - - exact_integer::operator std::uint32_t() const - { - return mpz_get_ui(value); - } - - exact_integer::operator std::uint64_t() const - { - return mpz_get_ui(value); - } - - exact_integer::operator float() const - { - return mpz_get_d(value); - } - - exact_integer::operator double() const - { - return mpz_get_d(value); - } - auto exact_integer::square_root() const -> std::tuple { exact_integer s, r; @@ -193,27 +98,6 @@ inline namespace kernel return std::make_tuple(s, r); } - auto operator ==(exact_integer const& a, int const b) -> bool { return a == static_cast(b); } - auto operator !=(exact_integer const& a, int const b) -> bool { return a != static_cast(b); } - auto operator < (exact_integer const& a, int const b) -> bool { return a < static_cast(b); } - auto operator <=(exact_integer const& a, int const b) -> bool { return a <= static_cast(b); } - auto operator > (exact_integer const& a, int const b) -> bool { return a > static_cast(b); } - auto operator >=(exact_integer const& a, int const b) -> bool { return a >= static_cast(b); } - - auto operator ==(exact_integer const& a, signed long const b) -> bool { return mpz_cmp_si(a.value, b) == 0; } - auto operator !=(exact_integer const& a, signed long const b) -> bool { return mpz_cmp_si(a.value, b) != 0; } - auto operator < (exact_integer const& a, signed long const b) -> bool { return mpz_cmp_si(a.value, b) < 0; } - auto operator <=(exact_integer const& a, signed long const b) -> bool { return mpz_cmp_si(a.value, b) <= 0; } - auto operator > (exact_integer const& a, signed long const b) -> bool { return mpz_cmp_si(a.value, b) > 0; } - auto operator >=(exact_integer const& a, signed long const b) -> bool { return mpz_cmp_si(a.value, b) >= 0; } - - auto operator ==(exact_integer const& a, unsigned long const b) -> bool { return mpz_cmp_ui(a.value, b) == 0; } - auto operator !=(exact_integer const& a, unsigned long const b) -> bool { return mpz_cmp_ui(a.value, b) != 0; } - auto operator < (exact_integer const& a, unsigned long const b) -> bool { return mpz_cmp_ui(a.value, b) < 0; } - auto operator <=(exact_integer const& a, unsigned long const b) -> bool { return mpz_cmp_ui(a.value, b) <= 0; } - auto operator > (exact_integer const& a, unsigned long const b) -> bool { return mpz_cmp_ui(a.value, b) > 0; } - auto operator >=(exact_integer const& a, unsigned long const b) -> bool { return mpz_cmp_ui(a.value, b) >= 0; } - auto operator <<(std::ostream & os, exact_integer const& datum) -> std::ostream & { return os << cyan(std::unique_ptr(mpz_get_str(nullptr, 10, datum.value)).get());