diff --git a/compiler+runtime/include/cpp/jank/runtime/core/make_box.hpp b/compiler+runtime/include/cpp/jank/runtime/core/make_box.hpp index f99ad28d..46de0569 100644 --- a/compiler+runtime/include/cpp/jank/runtime/core/make_box.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/core/make_box.hpp @@ -63,7 +63,7 @@ namespace jank::runtime [[gnu::always_inline, gnu::flatten, gnu::hot]] inline auto make_box(obj::ratio_data const r) { - return expect_object(obj::ratio::create(r.numerator, r.denominator)); + return make_box(r); } [[gnu::always_inline, gnu::flatten, gnu::hot]] diff --git a/compiler+runtime/include/cpp/jank/runtime/obj/ratio.hpp b/compiler+runtime/include/cpp/jank/runtime/obj/ratio.hpp index f01dca2e..c883a70d 100644 --- a/compiler+runtime/include/cpp/jank/runtime/obj/ratio.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/obj/ratio.hpp @@ -2,25 +2,17 @@ namespace jank::runtime { - template <> - struct static_object : gc - { - static constexpr native_bool pointer_free{ true }; - static_object() = default; - static_object(static_object &&) = default; - static_object(static_object const &) = default; - static_object(native_integer const numerator, native_integer const denominator); - - native_real to_real() const; - void simplify(); - - native_integer numerator{}; - native_integer denominator{}; - }; - namespace obj { - using ratio_data = static_object; + struct ratio_data + { + ratio_data(native_integer const, native_integer const); + ratio_data(ratio_data const &); + native_real to_real() const; + native_integer to_integer() const; + native_integer numerator{}; + native_integer denominator{}; + }; } template <> @@ -31,8 +23,9 @@ namespace jank::runtime static_object() = default; static_object(static_object &&) = default; static_object(static_object const &) = default; + static_object(obj::ratio_data const &); - static object_ptr create(native_integer const numerator, native_integer const denominator); + static object_ptr create(native_integer const, native_integer const); /* behavior::object_like */ native_bool equal(object const &) const; native_persistent_string to_string() const; @@ -51,7 +44,7 @@ namespace jank::runtime native_real to_real() const; object base{ object_type::ratio }; - obj::ratio_data data{}; + obj::ratio_data data; }; namespace obj @@ -78,15 +71,6 @@ namespace jank::runtime native_real operator-(native_real l, obj::ratio_data r); obj::ratio_ptr operator-(obj::ratio_data l, native_integer r); obj::ratio_ptr operator-(native_integer l, obj::ratio_data r); - object_ptr operator/(obj::ratio_data l, obj::ratio_data r); - object_ptr operator/(obj::integer_ptr l, obj::ratio_data r); - obj::ratio_ptr operator/(obj::ratio_data l, obj::integer_ptr r); - native_real operator/(obj::real_ptr l, obj::ratio_data r); - native_real operator/(obj::ratio_data l, obj::real_ptr r); - native_real operator/(obj::ratio_data l, native_real r); - native_real operator/(native_real l, obj::ratio_data r); - obj::ratio_ptr operator/(obj::ratio_data l, native_integer r); - object_ptr operator/(native_integer l, obj::ratio_data r); object_ptr operator*(obj::ratio_data l, obj::ratio_data r); object_ptr operator*(obj::integer_ptr l, obj::ratio_data r); object_ptr operator*(obj::ratio_data l, obj::integer_ptr r); @@ -96,6 +80,15 @@ namespace jank::runtime native_real operator*(native_real l, obj::ratio_data r); object_ptr operator*(obj::ratio_data l, native_integer r); object_ptr operator*(native_integer l, obj::ratio_data r); + object_ptr operator/(obj::ratio_data l, obj::ratio_data r); + object_ptr operator/(obj::integer_ptr l, obj::ratio_data r); + obj::ratio_ptr operator/(obj::ratio_data l, obj::integer_ptr r); + native_real operator/(obj::real_ptr l, obj::ratio_data r); + native_real operator/(obj::ratio_data l, obj::real_ptr r); + native_real operator/(obj::ratio_data l, native_real r); + native_real operator/(native_real l, obj::ratio_data r); + obj::ratio_ptr operator/(obj::ratio_data l, native_integer r); + object_ptr operator/(native_integer l, obj::ratio_data r); native_bool operator==(obj::ratio_data l, obj::ratio_data r); native_bool operator==(obj::integer_ptr l, obj::ratio_data r); native_bool operator==(obj::ratio_data l, obj::integer_ptr r); diff --git a/compiler+runtime/include/cpp/jank/runtime/object.hpp b/compiler+runtime/include/cpp/jank/runtime/object.hpp index 739f6c97..89cedec4 100644 --- a/compiler+runtime/include/cpp/jank/runtime/object.hpp +++ b/compiler+runtime/include/cpp/jank/runtime/object.hpp @@ -15,7 +15,6 @@ namespace jank::runtime integer, real, ratio, - ratio_data, persistent_string, persistent_string_sequence, diff --git a/compiler+runtime/src/cpp/jank/runtime/core/math.cpp b/compiler+runtime/src/cpp/jank/runtime/core/math.cpp index 5a050d18..49837e7c 100644 --- a/compiler+runtime/src/cpp/jank/runtime/core/math.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/core/math.cpp @@ -531,8 +531,8 @@ namespace jank::runtime [](auto const typed_l, auto const r) -> object_ptr { return visit_number_like( [](auto const typed_r, auto const typed_l) -> object_ptr { - auto typed_l_data = to_number(typed_l); - auto typed_r_data = to_number(typed_r->data); + auto const typed_l_data{ to_number(typed_l) }; + auto const typed_r_data{ to_number(typed_r->data) }; return make_box(std::fmod(typed_l_data, typed_r_data)); }, r, @@ -618,8 +618,8 @@ namespace jank::runtime [](auto const typed_l, auto const r) -> native_bool { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_bool { - auto data_l = to_number(typed_l); - auto data_r = to_number(typed_r->data); + auto const data_l{ to_number(typed_l) }; + auto const data_r{ to_number(typed_r->data) }; using C = std::common_type_t; #pragma clang diagnostic push @@ -1117,7 +1117,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::min(static_cast(typed_l), static_cast(typed_r_data)); }, @@ -1129,7 +1129,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::min(static_cast(typed_l_data), static_cast(typed_r)); }, @@ -1151,7 +1151,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::min(static_cast(typed_l_data), static_cast(typed_r)); }, @@ -1163,7 +1163,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::min(static_cast(typed_r_data), static_cast(typed_l)); }, @@ -1260,7 +1260,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::max(static_cast(typed_l), static_cast(typed_r_data)); }, @@ -1272,7 +1272,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::max(static_cast(typed_r), static_cast(typed_l_data)); }, @@ -1294,7 +1294,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::max(static_cast(typed_r), static_cast(typed_l_data)); }, @@ -1306,7 +1306,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::max(static_cast(typed_l), static_cast(typed_r_data)); }, @@ -1416,8 +1416,8 @@ namespace jank::runtime [](auto const typed_l, auto const r) -> native_real { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); - auto typed_l_data = to_number(typed_l); + auto const typed_r_data{ to_number(typed_r->data) }; + auto const typed_l_data{ to_number(typed_l) }; using C = std::common_type_t; return std::pow(static_cast(typed_l_data), static_cast(typed_r_data)); }, @@ -1432,8 +1432,8 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); - auto typed_l_data = to_number(typed_l); + auto const typed_r_data{ to_number(typed_r->data) }; + auto const typed_l_data{ to_number(typed_l) }; using C = std::common_type_t; return std::pow(static_cast(typed_l_data), static_cast(typed_r_data)); }, @@ -1445,7 +1445,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l_data), static_cast(typed_r)); }, @@ -1467,7 +1467,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l), static_cast(typed_r_data)); }, @@ -1479,7 +1479,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l_data), static_cast(typed_r)); }, @@ -1501,7 +1501,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l_data), static_cast(typed_r)); }, @@ -1513,7 +1513,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l), static_cast(typed_r_data)); }, @@ -1540,7 +1540,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_l, auto const typed_r) -> native_real { - auto typed_l_data = to_number(typed_l->data); + auto const typed_l_data{ to_number(typed_l->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l_data), static_cast(typed_r)); }, @@ -1552,7 +1552,7 @@ namespace jank::runtime { return visit_number_like( [](auto const typed_r, auto const typed_l) -> native_real { - auto typed_r_data = to_number(typed_r->data); + auto const typed_r_data{ to_number(typed_r->data) }; using C = std::common_type_t; return std::pow(static_cast(typed_l), static_cast(typed_r_data)); }, diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/ratio.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/ratio.cpp index 781722a2..39624e8a 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/ratio.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/ratio.cpp @@ -5,9 +5,9 @@ namespace jank::runtime { - constexpr native_real EPSILON = std::numeric_limits::epsilon(); + static constexpr auto epsilon{ std::numeric_limits::epsilon() }; - obj::ratio_data::static_object(native_integer numerator, native_integer denominator) + obj::ratio_data::ratio_data(native_integer const numerator, native_integer const denominator) : numerator{ numerator } , denominator{ denominator } { @@ -15,20 +15,36 @@ namespace jank::runtime { throw std::invalid_argument("Ratio denominator cannot be zero."); } - simplify(); + auto const gcd{ std::gcd(numerator, denominator) }; + this->numerator /= gcd; + this->denominator /= gcd; + + if(denominator < 0) + { + this->numerator = -1 * this->numerator; + this->denominator = -1 * this->denominator; + } + } + + obj::ratio_data::ratio_data(obj::ratio_data const &data) + : numerator{ data.numerator } + , denominator{ data.denominator } + { + } + + obj::ratio::static_object(obj::ratio_data const &data) + : data{ data } + { } object_ptr obj::ratio::create(native_integer const numerator, native_integer const denominator) { - auto ratio_data = make_box(numerator, denominator); - if(ratio_data->denominator == 1) + obj::ratio_data data{ numerator, denominator }; + if(data.denominator == 1) { - return make_box(ratio_data->numerator); + return make_box(data.numerator); } - auto r(make_box()); - r->data.numerator = ratio_data->numerator; - r->data.denominator = ratio_data->denominator; - return r; + return make_box(data); } native_real obj::ratio_data::to_real() const @@ -36,27 +52,19 @@ namespace jank::runtime return static_cast(numerator) / denominator; } - native_real obj::ratio::to_real() const + native_integer obj::ratio_data::to_integer() const { - return data.to_real(); + return numerator / denominator; } - native_integer obj::ratio::to_integer() const + native_real obj::ratio::to_real() const { - return data.numerator / data.denominator; + return data.to_real(); } - void obj::ratio_data::simplify() + native_integer obj::ratio::to_integer() const { - int gcd = std::gcd(numerator, denominator); - numerator /= gcd; - denominator /= gcd; - - if(denominator < 0) - { - numerator = -1 * numerator; - denominator = -1 * denominator; - } + return data.to_integer(); } void obj::ratio::to_string(fmt::memory_buffer &buff) const @@ -85,19 +93,17 @@ namespace jank::runtime { if(o.type == object_type::integer) { - auto const i(expect_object(&o)); - return this->data == i->data; + return data == expect_object(&o)->data; } if(o.type == object_type::real) { - auto const i(expect_object(&o)); - return this->data == i->data; + return data == expect_object(&o)->data; } if(o.type == object_type::ratio) { - return this == expect_object(&o).data; + return data == expect_object(&o)->data; } return false; @@ -122,101 +128,96 @@ namespace jank::runtime object_ptr operator+(obj::ratio_data const l, obj::ratio_data const r) { - native_integer denom = l.denominator * r.denominator; - native_integer num = l.numerator * r.denominator + r.numerator * l.denominator; + auto const denom{ l.denominator * r.denominator }; + auto const num{ l.numerator * r.denominator + r.numerator * l.denominator }; return obj::ratio::create(num, denom); } - obj::ratio_ptr operator+(obj::integer_ptr l, obj::ratio_data const r) + obj::ratio_ptr operator+(obj::integer_ptr const l, obj::ratio_data const r) { - return expect_object(obj::ratio_data(l->data, 1LL) + r); + return l->data + r; } - obj::ratio_ptr operator+(obj::ratio_data const l, obj::integer_ptr r) + obj::ratio_ptr operator+(obj::ratio_data const l, obj::integer_ptr const r) { return r + l; } - native_real operator+(obj::real_ptr l, obj::ratio_data const r) + native_real operator+(obj::real_ptr const l, obj::ratio_data const r) { return l->data + r.to_real(); } - native_real operator+(obj::ratio_data const l, obj::real_ptr r) + native_real operator+(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() + r->data; } - native_real operator+(obj::ratio_data const l, native_real r) + native_real operator+(obj::ratio_data const l, native_real const r) { return l.to_real() + r; } - native_real operator+(native_real l, obj::ratio_data const r) + native_real operator+(native_real const l, obj::ratio_data const r) { return l + r.to_real(); } - obj::ratio_ptr operator+(obj::ratio_data const l, native_integer r) + obj::ratio_ptr operator+(obj::ratio_data const l, native_integer const r) { - return expect_object( - obj::ratio::create(l.numerator + r * l.denominator, l.denominator)); + return make_box(obj::ratio_data(l.numerator + r * l.denominator, l.denominator)); } - obj::ratio_ptr operator+(native_integer l, obj::ratio_data const r) + obj::ratio_ptr operator+(native_integer const l, obj::ratio_data const r) { return r + l; } object_ptr operator-(obj::ratio_data const l, obj::ratio_data const r) { - native_integer denom = l.denominator * r.denominator; - native_integer num = l.numerator * r.denominator - r.numerator * l.denominator; + auto const denom{ l.denominator * r.denominator }; + auto const num{ l.numerator * r.denominator - r.numerator * l.denominator }; return obj::ratio::create(num, denom); } - obj::ratio_ptr operator-(obj::integer_ptr l, obj::ratio_data const r) + obj::ratio_ptr operator-(obj::integer_ptr const l, obj::ratio_data const r) { - return expect_object( - obj::ratio::create(l->data * r.denominator - r.numerator, r.denominator)); + return l->data - r; } - obj::ratio_ptr operator-(obj::ratio_data const l, obj::integer_ptr r) + obj::ratio_ptr operator-(obj::ratio_data const l, obj::integer_ptr const r) { - return expect_object( - obj::ratio::create(l.numerator - l.denominator * r->data, l.denominator)); + return l - r->data; } - native_real operator-(obj::real_ptr l, obj::ratio_data const r) + native_real operator-(obj::real_ptr const l, obj::ratio_data const r) { return l->data - r.to_real(); } - native_real operator-(obj::ratio_data const l, obj::real_ptr r) + native_real operator-(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() - r->data; } - native_real operator-(obj::ratio_data const l, native_real r) + native_real operator-(obj::ratio_data const l, native_real const r) { return l.to_real() - r; } - native_real operator-(native_real l, obj::ratio_data const r) + native_real operator-(native_real const l, obj::ratio_data const r) { return l - r.to_real(); } - obj::ratio_ptr operator-(obj::ratio_data const l, native_integer r) + obj::ratio_ptr operator-(obj::ratio_data const l, native_integer const r) { - return expect_object( - obj::ratio::create(l.numerator - r * l.denominator, l.denominator)); + return make_box(obj::ratio_data(l.numerator - r * l.denominator, l.denominator)); } - obj::ratio_ptr operator-(native_integer l, obj::ratio_data const r) + obj::ratio_ptr operator-(native_integer const l, obj::ratio_data const r) { - return expect_object( - obj::ratio::create(l * r.denominator - r.denominator, r.denominator)); + return make_box(obj::ratio_data(l * r.denominator - r.denominator, r.denominator)); } object_ptr operator*(obj::ratio_data const l, obj::ratio_data const r) @@ -224,42 +225,42 @@ namespace jank::runtime return obj::ratio::create(l.numerator * r.numerator, l.denominator * r.denominator); } - object_ptr operator*(obj::integer_ptr l, obj::ratio_data const r) + object_ptr operator*(obj::integer_ptr const l, obj::ratio_data const r) { return obj::ratio_data(l->data, 1LL) * r; } - object_ptr operator*(obj::ratio_data const l, obj::integer_ptr r) + object_ptr operator*(obj::ratio_data const l, obj::integer_ptr const r) { return l * obj::ratio_data(r->data, 1LL); } - native_real operator*(obj::real_ptr l, obj::ratio_data const r) + native_real operator*(obj::real_ptr const l, obj::ratio_data const r) { return l->data * r.to_real(); } - native_real operator*(obj::ratio_data const l, obj::real_ptr r) + native_real operator*(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() * r->data; } - native_real operator*(obj::ratio_data const l, native_real r) + native_real operator*(obj::ratio_data const l, native_real const r) { return l.to_real() * r; } - native_real operator*(native_real l, obj::ratio_data const r) + native_real operator*(native_real const l, obj::ratio_data const r) { return l * r.to_real(); } - object_ptr operator*(obj::ratio_data const l, native_integer r) + object_ptr operator*(obj::ratio_data const l, native_integer const r) { return l * obj::ratio_data(r, 1LL); } - object_ptr operator*(native_integer l, obj::ratio_data const r) + object_ptr operator*(native_integer const l, obj::ratio_data const r) { return r * l; } @@ -269,42 +270,42 @@ namespace jank::runtime return obj::ratio::create(l.numerator * r.denominator, l.denominator * r.numerator); } - object_ptr operator/(obj::integer_ptr l, obj::ratio_data const r) + object_ptr operator/(obj::integer_ptr const l, obj::ratio_data const r) { return obj::ratio_data(l->data, 1LL) / r; } - obj::ratio_ptr operator/(obj::ratio_data const l, obj::integer_ptr r) + obj::ratio_ptr operator/(obj::ratio_data const l, obj::integer_ptr const r) { - return expect_object(l / obj::ratio_data(r->data, 1LL)); + return l / r->data; } - native_real operator/(obj::real_ptr l, obj::ratio_data const r) + native_real operator/(obj::real_ptr const l, obj::ratio_data const r) { return l->data / r.to_real(); } - native_real operator/(obj::ratio_data const l, obj::real_ptr r) + native_real operator/(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() / r->data; } - native_real operator/(obj::ratio_data const l, native_real r) + native_real operator/(obj::ratio_data const l, native_real const r) { return l.to_real() / r; } - native_real operator/(native_real l, obj::ratio_data const r) + native_real operator/(native_real const l, obj::ratio_data const r) { return l / r.to_real(); } - obj::ratio_ptr operator/(obj::ratio_data const l, native_integer r) + obj::ratio_ptr operator/(obj::ratio_data const l, native_integer const r) { - return l / make_box(r); + return make_box(obj::ratio_data(l.numerator, l.denominator * r)); } - object_ptr operator/(native_integer l, obj::ratio_data const r) + object_ptr operator/(native_integer const l, obj::ratio_data const r) { return obj::ratio_data(l, 1LL) / r; } @@ -314,42 +315,42 @@ namespace jank::runtime return l.numerator == r.numerator && l.denominator == r.denominator; } - native_bool operator==(obj::integer_ptr l, obj::ratio_data const r) + native_bool operator==(obj::integer_ptr const l, obj::ratio_data const r) { return l->data * r.denominator == r.numerator; } - native_bool operator==(obj::ratio_data const l, obj::integer_ptr r) + native_bool operator==(obj::ratio_data const l, obj::integer_ptr const r) { return l.numerator == r->data * l.denominator; } - native_bool operator==(obj::real_ptr l, obj::ratio_data const r) + native_bool operator==(obj::real_ptr const l, obj::ratio_data const r) { - return std::fabs(l->data - r) < EPSILON; + return std::fabs(l->data - r) < epsilon; } - native_bool operator==(obj::ratio_data const l, obj::real_ptr r) + native_bool operator==(obj::ratio_data const l, obj::real_ptr const r) { return r == l; } - native_bool operator==(obj::ratio_data const l, native_real r) + native_bool operator==(obj::ratio_data const l, native_real const r) { - return std::fabs(l - r) < EPSILON; + return std::fabs(l - r) < epsilon; } - native_bool operator==(native_real l, obj::ratio_data const r) + native_bool operator==(native_real const l, obj::ratio_data const r) { return r == l; } - native_bool operator==(obj::ratio_data const l, native_integer r) + native_bool operator==(obj::ratio_data const l, native_integer const r) { return l.numerator == r * l.denominator; } - native_bool operator==(native_integer l, obj::ratio_data const r) + native_bool operator==(native_integer const l, obj::ratio_data const r) { return l * r.denominator == r.numerator; } @@ -364,82 +365,82 @@ namespace jank::runtime return l.numerator * r.denominator <= r.numerator * l.denominator; } - native_bool operator<(obj::integer_ptr l, obj::ratio_data const r) + native_bool operator<(obj::integer_ptr const l, obj::ratio_data const r) { return l->data * r.denominator < r.numerator; } - native_bool operator<(obj::ratio_data const l, obj::integer_ptr r) + native_bool operator<(obj::ratio_data const l, obj::integer_ptr const r) { return l.numerator < r->data * l.denominator; } - native_bool operator<=(obj::integer_ptr l, obj::ratio_data const r) + native_bool operator<=(obj::integer_ptr const l, obj::ratio_data const r) { return l->data * r.denominator <= r.numerator; } - native_bool operator<=(obj::ratio_data const l, obj::integer_ptr r) + native_bool operator<=(obj::ratio_data const l, obj::integer_ptr const r) { return l.numerator <= r->data * l.denominator; } - native_bool operator<(obj::real_ptr l, obj::ratio_data const r) + native_bool operator<(obj::real_ptr const l, obj::ratio_data const r) { return l->data < r.to_real(); } - native_bool operator<(obj::ratio_data const l, obj::real_ptr r) + native_bool operator<(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() < r->data; } - native_bool operator<=(obj::real_ptr l, obj::ratio_data const r) + native_bool operator<=(obj::real_ptr const l, obj::ratio_data const r) { return l->data <= r.to_real(); } - native_bool operator<=(obj::ratio_data const l, obj::real_ptr r) + native_bool operator<=(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() <= r->data; } - native_bool operator<(obj::ratio_data const l, native_real r) + native_bool operator<(obj::ratio_data const l, native_real const r) { return l.to_real() < r; } - native_bool operator<(native_real l, obj::ratio_data const r) + native_bool operator<(native_real const l, obj::ratio_data const r) { return l < r.to_real(); } - native_bool operator<=(obj::ratio_data const l, native_real r) + native_bool operator<=(obj::ratio_data const l, native_real const r) { return l.to_real() <= r; } - native_bool operator<=(native_real l, obj::ratio_data const r) + native_bool operator<=(native_real const l, obj::ratio_data const r) { return l <= r.to_real(); } - native_bool operator<(obj::ratio_data const l, native_integer r) + native_bool operator<(obj::ratio_data const l, native_integer const r) { return l.numerator < r * l.denominator; } - native_bool operator<(native_integer l, obj::ratio_data const r) + native_bool operator<(native_integer const l, obj::ratio_data const r) { return l * r.denominator < r.numerator; } - native_bool operator<=(obj::ratio_data const l, native_integer r) + native_bool operator<=(obj::ratio_data const l, native_integer const r) { return l.numerator <= r * l.denominator; } - native_bool operator<=(native_integer l, obj::ratio_data const r) + native_bool operator<=(native_integer const l, obj::ratio_data const r) { return l * r.denominator <= r.numerator; } @@ -449,42 +450,42 @@ namespace jank::runtime return l.numerator * r.denominator > r.numerator * l.denominator; } - native_bool operator>(obj::integer_ptr l, obj::ratio_data const r) + native_bool operator>(obj::integer_ptr const l, obj::ratio_data const r) { return l->data * r.denominator > r.numerator; } - native_bool operator>(obj::ratio_data const l, obj::integer_ptr r) + native_bool operator>(obj::ratio_data const l, obj::integer_ptr const r) { return l.numerator > r->data * l.denominator; } - native_bool operator>(obj::real_ptr l, obj::ratio_data const r) + native_bool operator>(obj::real_ptr const l, obj::ratio_data const r) { return l->data > r.to_real(); } - native_bool operator>(obj::ratio_data const l, obj::real_ptr r) + native_bool operator>(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() > r->data; } - native_bool operator>(obj::ratio_data const l, native_real r) + native_bool operator>(obj::ratio_data const l, native_real const r) { return l.to_real() > r; } - native_bool operator>(native_real l, obj::ratio_data const r) + native_bool operator>(native_real const l, obj::ratio_data const r) { return l > r.to_real(); } - native_bool operator>(obj::ratio_data const l, native_integer r) + native_bool operator>(obj::ratio_data const l, native_integer const r) { return l.numerator > r * l.denominator; } - native_bool operator>(native_integer l, obj::ratio_data const r) + native_bool operator>(native_integer const l, obj::ratio_data const r) { return l * r.denominator > r.numerator; } @@ -494,42 +495,42 @@ namespace jank::runtime return l.numerator * r.denominator >= r.numerator * l.denominator; } - native_bool operator>=(obj::integer_ptr l, obj::ratio_data const r) + native_bool operator>=(obj::integer_ptr const l, obj::ratio_data const r) { return l->data * r.denominator >= r.numerator; } - native_bool operator>=(obj::ratio_data const l, obj::integer_ptr r) + native_bool operator>=(obj::ratio_data const l, obj::integer_ptr const r) { return l.numerator >= r->data * l.denominator; } - native_bool operator>=(obj::real_ptr l, obj::ratio_data const r) + native_bool operator>=(obj::real_ptr const l, obj::ratio_data const r) { return l->data >= r.to_real(); } - native_bool operator>=(obj::ratio_data const l, obj::real_ptr r) + native_bool operator>=(obj::ratio_data const l, obj::real_ptr const r) { return l.to_real() >= r->data; } - native_bool operator>=(obj::ratio_data const l, native_real r) + native_bool operator>=(obj::ratio_data const l, native_real const r) { return l.to_real() >= r; } - native_bool operator>=(native_real l, obj::ratio_data const r) + native_bool operator>=(native_real const l, obj::ratio_data const r) { return l >= r.to_real(); } - native_bool operator>=(obj::ratio_data const l, native_integer r) + native_bool operator>=(obj::ratio_data const l, native_integer const r) { return l.numerator >= r * l.denominator; } - native_bool operator>=(native_integer l, obj::ratio_data const r) + native_bool operator>=(native_integer const l, obj::ratio_data const r) { return l * r.denominator >= r.numerator; } diff --git a/compiler+runtime/test/cpp/jank/runtime/obj/ratio.cpp b/compiler+runtime/test/cpp/jank/runtime/obj/ratio.cpp index 6d32afec..163b71fd 100644 --- a/compiler+runtime/test/cpp/jank/runtime/obj/ratio.cpp +++ b/compiler+runtime/test/cpp/jank/runtime/obj/ratio.cpp @@ -1,18 +1,20 @@ -#include "jank/runtime/obj/ratio.hpp" -#include #include +#include + +/* This must go last; doctest and glog both define CHECK and family. */ +#include namespace jank::runtime { - TEST_SUITE("ratio_data") + TEST_SUITE("ratio") { TEST_CASE("Ratio Constructor") { SUBCASE("Valid Ratio") { obj::ratio_data ratio{ 4, 6 }; - CHECK(ratio.numerator == 2); // Simplified - CHECK(ratio.denominator == 3); + CHECK_EQ(ratio.numerator, 2); // Simplified + CHECK_EQ(ratio.denominator, 3); } SUBCASE("Invalid Denominator") { @@ -23,33 +25,33 @@ namespace jank::runtime TEST_CASE("ToReal Conversion") { obj::ratio_data ratio{ 3, 4 }; - CHECK(ratio.to_real() == doctest::Approx(0.75)); + CHECK_EQ(ratio.to_real(), doctest::Approx(0.75)); } TEST_CASE("Simplify Functionality") { obj::ratio_data ratio{ 10, -20 }; - CHECK(ratio.numerator == -1); - CHECK(ratio.denominator == 2); + CHECK_EQ(ratio.numerator, -1); + CHECK_EQ(ratio.denominator, 2); } TEST_CASE("Create Ratio or Integer") { SUBCASE("Simplified to Integer") { - auto ratio_ptr = obj::ratio::create(4, 2); - CHECK(ratio_ptr->type == object_type::integer); + auto const ratio_ptr{ obj::ratio::create(4, 2) }; + CHECK_EQ(ratio_ptr->type, object_type::integer); REQUIRE(ratio_ptr != nullptr); - CHECK(expect_object(ratio_ptr)->data == 2); + CHECK_EQ(expect_object(ratio_ptr)->data, 2); } SUBCASE("Remains as Ratio") { - auto ratio_ptr = obj::ratio::create(3, 4); - auto ratio = expect_object(ratio_ptr); + auto const ratio_ptr{ obj::ratio::create(3, 4) }; + auto const ratio{ expect_object(ratio_ptr) }; REQUIRE(ratio != nullptr); - CHECK(ratio->data.numerator == 3); - CHECK(ratio->data.denominator == 4); - CHECK(ratio->to_real() == doctest::Approx(0.75)); + CHECK_EQ(ratio->data.numerator, 3); + CHECK_EQ(ratio->data.denominator, 4); + CHECK_EQ(ratio->to_real(), doctest::Approx(0.75)); } } @@ -59,28 +61,28 @@ namespace jank::runtime SUBCASE("Addition") { - auto result = *expect_object(a + b); - CHECK(result.data.numerator == 5); - CHECK(result.data.denominator == 6); + auto const result{ *expect_object(a + b) }; + CHECK_EQ(result.data.numerator, 5); + CHECK_EQ(result.data.denominator, 6); } SUBCASE("Subtraction") { - auto result = *expect_object(a - b); - CHECK(result.data.numerator == 1); - CHECK(result.data.denominator == 6); + auto const result{ *expect_object(a - b) }; + CHECK_EQ(result.data.numerator, 1); + CHECK_EQ(result.data.denominator, 6); } SUBCASE("Multiplication") { - auto result = *expect_object(a * b); - CHECK(result.data.numerator == 1); - CHECK(result.data.denominator == 6); + auto const result{ *expect_object(a * b) }; + CHECK_EQ(result.data.numerator, 1); + CHECK_EQ(result.data.denominator, 6); } SUBCASE("Division") { - auto result = *expect_object(a / b); - CHECK(result.data.numerator == 3); - CHECK(result.data.denominator == 2); + auto const result{ *expect_object(a / b) }; + CHECK_EQ(result.data.numerator, 3); + CHECK_EQ(result.data.denominator, 2); } } @@ -91,7 +93,7 @@ namespace jank::runtime SUBCASE("Equality") { CHECK(a == b); - CHECK_FALSE(a == c); + CHECK(a != c); } SUBCASE("Less Than") { @@ -111,20 +113,20 @@ namespace jank::runtime SUBCASE("Simplify on Negative Denominator") { - CHECK(ratio.numerator == -2); - CHECK(ratio.denominator == 3); + CHECK_EQ(ratio.numerator, -2); + CHECK_EQ(ratio.denominator, 3); } SUBCASE("ToString") { - auto ratio_ptr = obj::ratio::create(3, 4); - auto ratio = expect_object(ratio_ptr); - CHECK(ratio->to_string() == "3/4"); + auto const ratio_ptr{ obj::ratio::create(3, 4) }; + auto const ratio{ expect_object(ratio_ptr) }; + CHECK_EQ(ratio->to_string(), "3/4"); } SUBCASE("Hashing") { - auto ratio1 = expect_object(obj::ratio::create(2, 3)); - auto ratio2 = expect_object(obj::ratio::create(2, 3)); - CHECK(ratio1->to_hash() == ratio2->to_hash()); + auto const ratio1{ expect_object(obj::ratio::create(2, 3)) }; + auto const ratio2{ expect_object(obj::ratio::create(2, 3)) }; + CHECK_EQ(ratio1->to_hash(), ratio2->to_hash()); } } @@ -134,94 +136,94 @@ namespace jank::runtime SUBCASE("Addition with Native Integer") { - auto native_int{ make_box(2LL) }; - auto result = *(ratio + native_int); - auto result2 = *(native_int + ratio); - CHECK(result.data.numerator == 11); - CHECK(result.data.denominator == 4); - CHECK(result2.data.numerator == 11); - CHECK(result2.data.denominator == 4); + auto const native_int{ make_box(2LL) }; + auto const result{ *(ratio + native_int) }; + auto const result2{ *(native_int + ratio) }; + CHECK_EQ(result.data.numerator, 11); + CHECK_EQ(result.data.denominator, 4); + CHECK_EQ(result2.data.numerator, 11); + CHECK_EQ(result2.data.denominator, 4); } SUBCASE("Addition with Native Real") { - auto native_real{ make_box(0.5) }; - auto result = ratio + native_real; - auto result2 = native_real + ratio; - CHECK(result == doctest::Approx(1.25)); - CHECK(result2 == doctest::Approx(1.25)); + auto const native_real{ make_box(0.5) }; + auto const result{ ratio + native_real }; + auto const result2{ native_real + ratio }; + CHECK_EQ(result, doctest::Approx(1.25)); + CHECK_EQ(result2, doctest::Approx(1.25)); } SUBCASE("Subtraction with Integer Pointer") { - auto int_ptr = make_box(1); - auto result = ratio - int_ptr; - auto result2 = int_ptr - ratio; - CHECK(result->data.numerator == -1); - CHECK(result->data.denominator == 4); - CHECK(result2->data.numerator == 1); - CHECK(result2->data.denominator == 4); + auto const int_ptr{ make_box(1) }; + auto const result{ ratio - int_ptr }; + auto const result2{ int_ptr - ratio }; + CHECK_EQ(result->data.numerator, -1); + CHECK_EQ(result->data.denominator, 4); + CHECK_EQ(result2->data.numerator, 1); + CHECK_EQ(result2->data.denominator, 4); } SUBCASE("Subtraction with Native Real") { - auto native_real{ make_box(0.25) }; - auto result = ratio - native_real; - auto result2 = native_real - ratio; - CHECK(result == doctest::Approx(0.5)); - CHECK(result2 == doctest::Approx(-0.5)); + auto const native_real{ make_box(0.25) }; + auto const result{ ratio - native_real }; + auto const result2{ native_real - ratio }; + CHECK_EQ(result, doctest::Approx(0.5)); + CHECK_EQ(result2, doctest::Approx(-0.5)); } SUBCASE("Multiplication with Integer Pointer") { - auto int_ptr{ make_box(3) }; - auto result = *expect_object(ratio * int_ptr); - auto result2 = *expect_object(int_ptr * ratio); - CHECK(result.data.numerator == 9); - CHECK(result.data.denominator == 4); - CHECK(result2.data.numerator == 9); - CHECK(result2.data.denominator == 4); + auto const int_ptr{ make_box(3) }; + auto const result{ *expect_object(ratio * int_ptr) }; + auto const result2{ *expect_object(int_ptr * ratio) }; + CHECK_EQ(result.data.numerator, 9); + CHECK_EQ(result.data.denominator, 4); + CHECK_EQ(result2.data.numerator, 9); + CHECK_EQ(result2.data.denominator, 4); } SUBCASE("Multiplication with Native Real") { - auto native_real{ 0.5L }; - auto result = ratio * native_real; - auto result2 = native_real * ratio; - CHECK(result == doctest::Approx(0.375)); - CHECK(result2 == doctest::Approx(0.375)); + auto const native_real{ 0.5L }; + auto const result{ ratio * native_real }; + auto const result2{ native_real * ratio }; + CHECK_EQ(result, doctest::Approx(0.375)); + CHECK_EQ(result2, doctest::Approx(0.375)); } SUBCASE("Division with Native Integer") { - auto native_int{ 2LL }; - auto result = ratio / native_int; - auto result2 = expect_object(native_int / ratio); - CHECK(result->data.numerator == 3); - CHECK(result->data.denominator == 8); - CHECK(result2->data.numerator == 8); - CHECK(result2->data.denominator == 3); + auto const native_int{ 2LL }; + auto const result{ ratio / native_int }; + auto const result2{ expect_object(native_int / ratio) }; + CHECK_EQ(result->data.numerator, 3); + CHECK_EQ(result->data.denominator, 8); + CHECK_EQ(result2->data.numerator, 8); + CHECK_EQ(result2->data.denominator, 3); } SUBCASE("Division with Native Real") { - auto native_real{ 0.5L }; - auto result = ratio / native_real; - auto result2 = native_real / ratio; - CHECK(result == doctest::Approx(1.5)); - CHECK(result2 == doctest::Approx(1 / 1.5)); + auto const native_real{ 0.5L }; + auto const result{ ratio / native_real }; + auto const result2{ native_real / ratio }; + CHECK_EQ(result, doctest::Approx(1.5)); + CHECK_EQ(result2, doctest::Approx(1 / 1.5)); } SUBCASE("Comparison with Integer Pointer") { - auto int_ptr{ make_box(1LL) }; - CHECK(ratio < int_ptr); - CHECK(ratio != int_ptr); - CHECK(int_ptr > ratio); - CHECK(int_ptr != ratio); + auto const int_ptr{ make_box(1LL) }; + CHECK_LT(ratio, int_ptr); + CHECK_NE(ratio, int_ptr); + CHECK_GT(int_ptr, ratio); + CHECK_NE(int_ptr, ratio); } SUBCASE("Comparison with Native Integer") { - auto native_int{ 1LL }; + auto const native_int{ 1LL }; CHECK(ratio < native_int); CHECK(ratio != native_int); CHECK(native_int > ratio); @@ -230,7 +232,7 @@ namespace jank::runtime SUBCASE("Comparison with Native Real") { - auto native_real{ 0.75L }; + auto const native_real{ 0.75L }; CHECK(ratio == native_real); CHECK(native_real == ratio); } @@ -239,24 +241,24 @@ namespace jank::runtime TEST_CASE("Ratio Mixed Arithmetic and Comparisons") { obj::ratio_data ratio{ 5, 8 }; - auto native_int{ 3LL }; - auto native_real{ 0.25L }; + auto const native_int{ 3LL }; + auto const native_real{ 0.25L }; SUBCASE("Complex Arithmetic Chain") { - auto result = (ratio + native_int)->data - native_real; - CHECK(result == doctest::Approx(3.375)); + auto const result{ (ratio + native_int)->data - native_real }; + CHECK_EQ(result, doctest::Approx(3.375)); } SUBCASE("Mixed Comparison") { - auto real_ptr{ make_box(1.0L) }; - auto int_ptr{ make_box(1LL) }; + auto const real_ptr{ make_box(1.0L) }; + auto const int_ptr{ make_box(1LL) }; - CHECK(ratio < real_ptr); - CHECK(ratio < int_ptr); - CHECK(real_ptr > ratio); - CHECK(int_ptr > ratio); + CHECK_LT(ratio, real_ptr); + CHECK_LT(ratio, int_ptr); + CHECK_GT(real_ptr, ratio); + CHECK_GT(int_ptr, ratio); } } @@ -264,15 +266,16 @@ namespace jank::runtime { SUBCASE("Ratio Divided by Zero") { - auto result = obj::ratio_data(1, 2) / 0.0L; + auto const result{ obj::ratio_data(1, 2) / 0.0L }; CHECK(std::isinf(result)); - CHECK(result > 0); - CHECK(result == std::numeric_limits::infinity()); + CHECK_GT(result, 0); + CHECK_EQ(result, std::numeric_limits::infinity()); - auto neg_result = expect_object(-1LL * obj::ratio_data(1, 2))->data / 0.0L; + auto const neg_result{ expect_object(-1LL * obj::ratio_data(1, 2))->data + / 0.0L }; CHECK(std::isinf(neg_result)); - CHECK(neg_result < 0); - CHECK(neg_result == -std::numeric_limits::infinity()); + CHECK_LT(neg_result, 0); + CHECK_EQ(neg_result, -std::numeric_limits::infinity()); CHECK_THROWS_AS((obj::ratio_data(1, 2) / 0LL), std::invalid_argument); CHECK_THROWS_AS((obj::ratio_data(1, 2) / obj::ratio_data(0, 1)), std::invalid_argument); @@ -280,122 +283,114 @@ namespace jank::runtime SUBCASE("Ratio Multiplied by Negative Integer") { - auto result = expect_object(obj::ratio_data(2, 3) * -4LL); - CHECK(result->data.numerator == -8); - CHECK(result->data.denominator == 3); + auto const result{ expect_object(obj::ratio_data(2, 3) * -4LL) }; + CHECK_EQ(result->data.numerator, -8); + CHECK_EQ(result->data.denominator, 3); } } } - TEST_SUITE("ratio") + TEST_CASE("constructor") { - obj::ratio_ptr make_ptr(native_integer num, native_integer denom) - { - auto r(make_box()); - r->data.numerator = num; - r->data.denominator = denom; - return r; - } - - TEST_CASE("constructor") - { - auto a = expect_object(obj::ratio::create(3, 4)); - CHECK(a->data.numerator == 3); - CHECK(a->data.denominator == 4); - } - - TEST_CASE("to_real") - { - auto a = make_ptr(3, 4); - CHECK(a->to_real() == 3.0 / 4.0); - } + auto const a{ expect_object(obj::ratio::create(3, 4)) }; + CHECK_EQ(a->data.numerator, 3); + CHECK_EQ(a->data.denominator, 4); + } - TEST_CASE("to_integer") - { - auto a = make_ptr(7, 4); - CHECK(a->to_integer() == 1); - } + TEST_CASE("to_real") + { + auto const a{ make_box(obj::ratio_data(3, 4)) }; + CHECK_EQ(a->to_real(), 3.0 / 4.0); + } - TEST_CASE("to_string") - { - auto a = make_ptr(3, 4); - CHECK(a->to_string() == "3/4"); - } + TEST_CASE("to_integer") + { + auto const a{ make_box(obj::ratio_data(7, 4)) }; + CHECK_EQ(a->to_integer(), 1); + } + TEST_CASE("to_string") + { + auto const a{ make_box(obj::ratio_data(3, 4)) }; + CHECK_EQ(a->to_string(), "3/4"); + } - TEST_CASE("compare_less_than") - { - auto a = make_ptr(3, 4); - auto b = make_ptr(5, 4); - CHECK(a->compare(*b) < 0); - } + TEST_CASE("compare_less_than") + { + auto const a{ make_box(obj::ratio_data(3, 4)) }; + auto const b{ make_box(obj::ratio_data(5, 4)) }; + CHECK_LT(a->compare(*b), 0); + } - TEST_CASE("compare_greater_than") - { - auto a = make_ptr(5, 4); - auto b = make_ptr(3, 4); - CHECK(a->compare(*b) > 0); - } + TEST_CASE("compare_greater_than") + { + auto const a{ make_box(obj::ratio_data(5, 4)) }; + auto const b{ make_box(obj::ratio_data(3, 4)) }; + CHECK_GT(a->compare(*b), 0); + } - TEST_CASE("compare_equal") - { - auto a = make_ptr(3, 4); - auto b = make_ptr(3, 4); - CHECK(a->compare(*b) == 0); - } + TEST_CASE("compare_equal") + { + auto const a{ make_box(obj::ratio_data(3, 4)) }; + auto const b{ make_box(obj::ratio_data(3, 4)) }; + CHECK_EQ(a->compare(*b), 0); + } - TEST_CASE("is_zero") - { - CHECK(is_zero(make_ptr(0, 1))); - } + TEST_CASE("is_zero") + { + CHECK(is_zero(make_box(obj::ratio_data(0, 1)))); + } - TEST_CASE("is_positive") - { - obj::ratio; - CHECK(is_pos(make_ptr(3, 4))); - } + TEST_CASE("is_positive") + { + obj::ratio; + CHECK(is_pos(make_box(obj::ratio_data(3, 4)))); + } - TEST_CASE("is_negative") - { - CHECK(is_neg(make_ptr(-3, 4))); - } + TEST_CASE("is_negative") + { + CHECK(is_neg(make_box(obj::ratio_data(-3, 4)))); + } - TEST_CASE("is_equivalent") - { - CHECK(is_equiv(make_ptr(3, 4), make_ptr(6, 8))); - } + TEST_CASE("is_equivalent") + { + CHECK(is_equiv(make_box(obj::ratio_data(3, 4)), + make_box(obj::ratio_data(6, 8)))); + } - TEST_CASE("increment") - { - auto result = expect_object(inc(make_ptr(3, 4))); - CHECK(result->data.numerator == 7); - CHECK(result->data.denominator == 4); - } + TEST_CASE("increment") + { + auto const result{ expect_object( + inc(make_box(obj::ratio_data(3, 4)))) }; + CHECK_EQ(result->data.numerator, 7); + CHECK_EQ(result->data.denominator, 4); + } - TEST_CASE("decrement") - { - auto result = expect_object(dec(make_ptr(3, 4))); - CHECK(result->data.numerator == -1); - CHECK(result->data.denominator == 4); - } + TEST_CASE("decrement") + { + auto const result{ expect_object( + dec(make_box(obj::ratio_data(3, 4)))) }; + CHECK_EQ(result->data.numerator, -1); + CHECK_EQ(result->data.denominator, 4); + } - TEST_CASE("abs") - { - auto result = expect_object(abs(make_ptr(-3, 4))); - CHECK(result->data.numerator == 3); - CHECK(result->data.denominator == 4); - } + TEST_CASE("abs") + { + auto const result{ expect_object( + abs(make_box(obj::ratio_data(-3, 4)))) }; + CHECK_EQ(result->data.numerator, 3); + CHECK_EQ(result->data.denominator, 4); + } - TEST_CASE("sqrt") - { - auto result = make_ptr(3, 4); - CHECK(sqrt(result) == doctest::Approx(std::sqrt(3.0 / 4.0))); - } + TEST_CASE("sqrt") + { + auto const result{ make_box(obj::ratio_data(3, 4)) }; + CHECK_EQ(sqrt(result), doctest::Approx(std::sqrt(3.0 / 4.0))); + } - TEST_CASE("pow") - { - auto a = make_ptr(3, 4); - CHECK(pow(a, a) == doctest::Approx(std::pow(3.0 / 4.0, 3.0 / 4.0))); - } + TEST_CASE("pow") + { + auto const a{ make_box(obj::ratio_data(3, 4)) }; + CHECK_EQ(pow(a, a), doctest::Approx(std::pow(3.0 / 4.0, 3.0 / 4.0))); } }