/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #pragma once #include namespace std { namespace detail { template struct GCD { static constexpr intmax_t value = GCD::value; }; template struct GCD { static constexpr intmax_t value = A; }; } template class ratio { private: static_assert(Denom != 0, "Denominator cannot be zero"); static_assert(Num >= -__INTMAX_MAX__ && Denom >= -__INTMAX_MAX__, "Overflow"); private: static constexpr intmax_t __first = Num < 0 ? -Num : Num; static constexpr intmax_t __second = Denom < 0 ? -Denom : Denom; static constexpr intmax_t __gcd = detail::GCD<__first, __second>::value; public: typedef ratio type; static constexpr intmax_t num = Denom < 0 ? -Num / __gcd : Num / __gcd; static constexpr intmax_t den = Denom < 0 ? -Denom / __gcd : Denom / __gcd; }; namespace detail { template constexpr bool __ta_is_ratio = false; template constexpr bool __ta_is_ratio> = true; template constexpr bool __is_equal() { return R1::num == R2::num && R1::den == R2::den; } template constexpr bool __is_less() { return R1::num * R2::den < R2::num * R1::den; } template constexpr bool __is_less_or_equal() { return R1::num * R2::den <= R2::num * R1::den; } template constexpr bool __is_greater() { return R1::num * R2::den > R2::num * R1::den; } template constexpr bool __is_greater_or_equal() { return R1::num * R2::den >= R2::num * R1::den; } }; template struct ratio_add { static_assert(detail::__ta_is_ratio && detail::__ta_is_ratio, "Both template arguments must be std::ratio"); static constexpr intmax_t num = R1::num * R2::den + R2::num * R1::den; static constexpr intmax_t den = R1::den * R2::den; using type = ratio; }; template struct ratio_subtract { static_assert(detail::__ta_is_ratio && detail::__ta_is_ratio, "Both template arguments must be std::ratio"); static constexpr intmax_t num = R1::num * R2::den - R2::num * R1::den; static constexpr intmax_t den = R1::den * R2::den; using type = ratio; }; template struct ratio_multiply { static_assert(detail::__ta_is_ratio && detail::__ta_is_ratio, "Both templates must be ratios"); static constexpr intmax_t num = R1::num * R2::num; static constexpr intmax_t den = R1::den * R2::den; using type = ratio; }; template struct ratio_divide { static_assert(R2::num != 0, "Divide by zero"); static constexpr intmax_t num = R1::num * R2::den; static constexpr intmax_t den = R1::den * R2::num; using type = ratio; }; template struct ratio_equal : public std::integral_constant()> { }; template struct ratio_not_equal : public std::integral_constant()> { }; template struct ratio_less : public std::integral_constant()> { }; template struct ratio_less_equal : public std::integral_constant()> { }; template struct ratio_greater : public std::integral_constant()> { }; template struct ratio_greater_equal : public std::integral_constant()> { }; template constexpr bool ratio_equal_v = ratio_equal::value; template constexpr bool ratio_not_equal_v = ratio_not_equal::value; template constexpr bool ratio_less_v = ratio_less::value; template constexpr bool ratio_less_equal_v = ratio_less_equal::value; template constexpr bool ratio_greater_v = ratio_greater::value; template constexpr bool ratio_greater_equal_v = ratio_greater_equal::value; // typedef ratio<1, 1000000000000000000000000000000> quecto; // typedef ratio<1, 1000000000000000000000000000> ronto; // typedef ratio<1, 1000000000000000000000000> yocto; // typedef ratio<1, 1000000000000000000000> zepto; typedef ratio<1, 1000000000000000000> atto; typedef ratio<1, 1000000000000000> femto; typedef ratio<1, 1000000000000> pico; typedef ratio<1, 1000000000> nano; typedef ratio<1, 1000000> micro; typedef ratio<1, 1000> milli; typedef ratio<1, 100> centi; typedef ratio<1, 10> deci; typedef ratio<10, 1> deca; typedef ratio<100, 1> hecto; typedef ratio<1000, 1> kilo; typedef ratio<1000000, 1> mega; typedef ratio<1000000000, 1> giga; typedef ratio<1000000000000, 1> tera; typedef ratio<1000000000000000, 1> peta; typedef ratio<1000000000000000000, 1> exa; // typedef ratio<1000000000000000000000, 1> zetta; // typedef ratio<1000000000000000000000000, 1> yotta; // typedef ratio<1000000000000000000000000000, 1> ronna; // typedef ratio<1000000000000000000000000000000, 1> quetta; }