У меня есть простая шаблонная метапрограмма, которая преобразует множество std::ratio
с в минимально возможное число ratio
с. Он должен возвращать 1 ratio
, если переполнения нет (и он делает это), и 2 или более, когда переполнения нет. Можно ли достичь?
template<class R, class ...Rs> struct unite_ratio;
template<intmax_t Num, intmax_t Den>
struct unite_ratio<std::ratio<Num, Den>>
{
using type = std::ratio<Num, Den>;
};
template<
intmax_t Num1, intmax_t Den1,
intmax_t Num2, intmax_t Den2,
class ...Rs
> struct unite_ratio<std::ratio<Num1, Den1>, std::ratio<Num2, Den2>, Rs...>
{
// here might be an overflow
static constexpr intmax_t num =
std::__static_sign<Den1>::value * std::__static_sign<Den2>::value *
(Num1 / std::__static_gcd<Num1, Den2>::value) *
(Num2 / std::__static_gcd<Num2, Den1>::value);
// Here might be an overflow as well
static constexpr intmax_t den =
(std::__static_abs<Den1>::value / std::__static_gcd<Num2, Den1>::value) *
(std::__static_abs<Den2>::value / std::__static_gcd<Num1, Den2>::value);
// returns only one type
using type = unite_ratio<std::ratio<num, den>, Rs...>;
};