gcd_lcm.hpp 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #ifndef BOOST_RATIO_DETAIL_GCD_LCM_HPP
  2. #define BOOST_RATIO_DETAIL_GCD_LCM_HPP
  3. // Copyright 2023 Peter Dimov
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // https://www.boost.org/LICENSE_1_0.txt
  6. #include <type_traits>
  7. #include <cstdint>
  8. namespace boost
  9. {
  10. namespace ratio_detail
  11. {
  12. template<std::intmax_t A> struct abs_: std::integral_constant<std::intmax_t, A < 0? -A: A>
  13. {
  14. };
  15. template<> struct abs_<INTMAX_MIN>: std::integral_constant<std::intmax_t, INTMAX_MIN>
  16. {
  17. };
  18. template<std::intmax_t A, std::intmax_t B> struct gcd_: public gcd_<B, A % B>
  19. {
  20. };
  21. template<std::intmax_t A> struct gcd_<A, 0>: std::integral_constant<std::intmax_t, A>
  22. {
  23. };
  24. template<std::intmax_t A, std::intmax_t B> struct lcm_: std::integral_constant<std::intmax_t, (A / gcd_<A, B>::value) * B>
  25. {
  26. };
  27. template<> struct lcm_<0, 0>: std::integral_constant<std::intmax_t, 0>
  28. {
  29. };
  30. //
  31. template<std::intmax_t A, std::intmax_t B> struct gcd: abs_< gcd_<A, B>::value >
  32. {
  33. };
  34. template<std::intmax_t A, std::intmax_t B> struct lcm: abs_< lcm_<A, B>::value >
  35. {
  36. };
  37. } // namespace ratio_detail
  38. } // namespace boost
  39. #endif // BOOST_RATIO_DETAIL_GCD_LCM_HPP