5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_RATIO_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_RATIO_HPP_
14#include "arene/base/math/abs.hpp"
15#include "arene/base/math/gcd.hpp"
16#include "arene/base/utility/swap.hpp"
17#include "stdlib/include/stdlib_detail/cstdint.hpp"
18#include "stdlib/include/stdlib_detail/numeric_limits.hpp"
26template <intmax_t N, intmax_t D = 1>
28 static_assert(D != 0,
"Denominator of a ratio must not be 0");
37 static constexpr intmax_t d_sign{D > 0 ? 1 : -1};
60template <intmax_t N, intmax_t D>
66template <
class R1,
class R2>
68 static_assert(
is_ratio<R1>::value,
"Parameters to ratio arithmetic operations must be specializations of std::ratio");
69 static_assert(
is_ratio<R2>::value,
"Parameters to ratio arithmetic operations must be specializations of std::ratio");
85template <
class R1,
class R2>
87 static_assert(
is_ratio<R1>::value,
"Parameters to ratio arithmetic operations must be specializations of std::ratio");
88 static_assert(
is_ratio<R2>::value,
"Parameters to ratio arithmetic operations must be specializations of std::ratio");
110template <
class R1,
class R2>
112 static_assert(
is_ratio<R1>::value,
"Parameters to ratio comparison operations must be specializations of std::ratio");
113 static_assert(
is_ratio<R2>::value,
"Parameters to ratio comparison operations must be specializations of std::ratio");
135 return (left.num == 0) || (right.num == 0) ||
136 ((left.num <= numeric_limits<intmax_t>::max() / right.den) &&
137 (right.num <= numeric_limits<intmax_t>::max() / left.den));
145 bool flip_direction{
false};
149 if (right.num >= 0) {
153 flip_direction = !flip_direction;
154 left.num = -left.num;
155 right.num = -right.num;
162 if ((left.num > left.den) != (right.num > right.den)) {
163 return right.num > right.den;
169 flip_direction = !flip_direction;
170 ::arene::base::swap(left.num, left.den);
171 ::arene::base::swap(right.num, right.den);
174 intmax_t
const left_integ{left.num / left.den};
175 intmax_t
const right_integ{right.num / right.den};
176 if (left_integ != right_integ) {
177 left = {left_integ, 1};
178 right = {right_integ, 1};
183 left.num %= left.den;
184 right.num %= right.den;
187 return flip_direction ? right.num * left.den < right.den * left.num : left.num * right.den < left.den * right.num;
195template <
class R1,
class R2>
197 static_assert(
is_ratio<R1>::value,
"Parameters to ratio comparison operations must be specializations of std::ratio");
198 static_assert(
is_ratio<R2>::value,
"Parameters to ratio comparison operations must be specializations of std::ratio");
212template <
class R1,
class R2>
222template <
class R1,
class R2>
232template <
class R1,
class R2>
240template <
class R1,
class R2>
246template <
class R1,
class R2>
252template <
class R1,
class R2>
258template <
class R1,
class R2>
264template <
class R1,
class R2>
270template <
class R1,
class R2>
276template <
class R1,
class R2>
281using atto =
ratio<1, 1'000'000'000'000'000'000>;
283using femto =
ratio<1, 1'000'000'000'000'000>;
285using pico =
ratio<1, 1'000'000'000'000>;
287using nano =
ratio<1, 1'000'000'000>;
305using giga =
ratio<1'000'000'000, 1>;
307using tera =
ratio<1'000'000'000'000, 1>;
309using peta =
ratio<1'000'000'000'000'000, 1>;
311using exa =
ratio<1'000'000'000'000'000'000, 1>;
A type trait to check if a type is a specialization of std::ratio as required in [ratio....
Definition ratio.hpp:55
A helper for addition to enforce the type requirement in [ratio.general] and improve readability.
Definition ratio.hpp:86
A helper for equality comparison to enforce the type requirement in [ratio.general].
Definition ratio.hpp:111
A helper for less-than comparison to enforce the type requirement in [ratio.general].
Definition ratio.hpp:196
A helper for multiplication to enforce the type requirement in [ratio.general] and improve readabilit...
Definition ratio.hpp:67
Inherits from true_type if the first ratio is equal to the second, false_type if not.
Definition ratio.hpp:247
Inherits from true_type if the first ratio is greater than or equal to the second,...
Definition ratio.hpp:277
Inherits from true_type if the first ratio is greater than the second, false_type if not.
Definition ratio.hpp:271
Inherits from true_type if the first ratio is less than or equal to the second, false_type if not.
Definition ratio.hpp:265
Inherits from true_type if the first ratio is less than the second, false_type if not.
Definition ratio.hpp:259
Inherits from true_type if the first ratio is not equal to the second, false_type if they are equal.
Definition ratio.hpp:253
A compile-time ratio of two integers, automatically reduced to lowest terms.
Definition ratio.hpp:27
static constexpr intmax_t num
The numerator of the ratio, reduced to lowest terms.
Definition ratio.hpp:43
static constexpr intmax_t den
The denominator of the ratio, reduced to lowest terms.
Definition ratio.hpp:45
constexpr auto can_directly_compare(fraction const &left, fraction const &right) noexcept -> bool
Check if two fractions can be directly compared (by cross multiplying them) without overflowing.
Definition ratio.hpp:134
constexpr auto fraction_less(fraction left, fraction right) noexcept -> bool
Check if the left fraction is less than the right or not.
Definition ratio.hpp:144
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827
A type used to represent a fraction for non-template computations.
Definition ratio.hpp:121
intmax_t num
The numerator of the fraction.
Definition ratio.hpp:123
intmax_t den
The denominator of the fraction.
Definition ratio.hpp:125