inline SPROUT_CONSTEXPR bool operator<(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) { return sprout::detail::rational_less_impl( lhs, rhs, lhs.numerator() / lhs.denominator(), lhs.numerator() % lhs.denominator() ); }
inline SPROUT_CONSTEXPR sprout::rational<IntType> operator+(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) { return sprout::detail::rational_add_impl( lhs, rhs, sprout::gcd(lhs.denominator(), rhs.denominator()) ); }
inline SPROUT_CONSTEXPR sprout::rational<IntType> abs(sprout::rational<IntType> const& x) { return x.numerator() >= IntType(0) ? x : sprout::detail::rational_construct_access<IntType>::raw_construct( -x.numerator(), x.denominator() ) ; }
inline SPROUT_CONSTEXPR sprout::rational<IntType> rational_add_impl_1( sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs, IntType g, IntType den ) { return rational_add_impl_2( rhs, g, den, lhs.numerator() * (rhs.denominator() / g) + rhs.numerator() * den ); }
inline SPROUT_CONSTEXPR sprout::rational<IntType> rational_div_impl( sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs, IntType gcd1, IntType gcd2 ) { return sprout::detail::rational_div_impl_1( (lhs.numerator() / gcd1) * (rhs.denominator() / gcd2), (lhs.denominator() / gcd2) * (rhs.numerator() / gcd1) ); }
inline SPROUT_CONSTEXPR sprout::rational<IntType> rational_mul_impl( sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs, IntType gcd1, IntType gcd2 ) { return sprout::detail::rational_construct_access<IntType>::raw_construct( (lhs.numerator() / gcd1) * (rhs.numerator() / gcd2), (lhs.denominator() / gcd2) * (rhs.denominator() / gcd1) ); }
inline SPROUT_CONSTEXPR bool rational_less_impl( sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs, IntType d1, IntType q1, IntType r1 ) { return r1 < IntType(0) ? sprout::detail::rational_less_impl( lhs, rhs, d1, q1 - 1, r1 + d1 ) : sprout::detail::rational_less_impl_1( lhs, rhs, d1, q1, r1, rhs.denominator(), rhs.numerator() / rhs.denominator(), rhs.numerator() % rhs.denominator() ) ; }
inline SPROUT_CONSTEXPR sprout::rational<IntType> rational_add_impl_3( sprout::rational<IntType> const& rhs, IntType g, IntType den, IntType num ) { return sprout::detail::rational_construct_access<IntType>::raw_construct( num / g, den * (rhs.denominator() / g) ); }
inline SPROUT_CONSTEXPR sprout::rational<IntType> rational_add_impl( sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs, IntType g ) { return rational_add_impl_1( lhs, rhs, g, lhs.denominator() / g ); }
inline SPROUT_CONSTEXPR bool rational_less_impl( sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs, IntType q, IntType r ) { return r < IntType(0) ? sprout::detail::rational_less_impl( lhs, rhs, r + lhs.denominator(), q - 1 ) : q < rhs ; }
inline SPROUT_CONSTEXPR sprout::rational<IntType> operator/(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) { return rhs.numerator() == IntType(0) ? throw sprout::bad_rational() : lhs.numerator() == IntType(0) ? lhs : sprout::detail::rational_div_impl( lhs, rhs, sprout::gcd(lhs.numerator(), rhs.numerator()), sprout::gcd(rhs.denominator(), lhs.denominator()) ) ; }
inline SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(std::basic_istream<Elem, Traits>& lhs, sprout::rational<IntType>& rhs) { IntType n = IntType(0); IntType d = IntType(1); Elem c = 0; sprout::detail::io::ios_flags_saver saver(lhs); lhs >> n; c = lhs.get(); if (c != Elem('/')) { lhs.clear(std::istream::badbit); } lhs >> std::noskipws; lhs >> d; if (lhs) { rhs.assign(n, d); } return lhs; }
inline SPROUT_CONSTEXPR std::size_t hash_value(sprout::rational<T> const& v) { return sprout::hash_values(v.numerator(), v.denominator()); }
inline SPROUT_CONSTEXPR bool operator==(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) { return lhs.denominator() == IntType(1) && lhs.numerator() == rhs; }
inline SPROUT_CONSTEXPR bool operator==(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) { return lhs.numerator() == rhs.numerator() && lhs.denominator() == rhs.denominator(); }
inline SPROUT_CONSTEXPR T rational_cast(sprout::rational<IntType> const& src) { return static_cast<T>(src.numerator()) / static_cast<T>(src.denominator()); }