div.hpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // (C) Copyright Matt Borland 2021.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_CCMATH_DIV_HPP
  6. #define BOOST_MATH_CCMATH_DIV_HPP
  7. #include <cmath>
  8. #include <cstdlib>
  9. #include <cinttypes>
  10. #include <cstdint>
  11. #include <type_traits>
  12. #include <boost/math/tools/is_standalone.hpp>
  13. #ifndef BOOST_MATH_STANDALONE
  14. #include <boost/config.hpp>
  15. #ifdef BOOST_NO_CXX17_IF_CONSTEXPR
  16. #error "The header <boost/math/norms.hpp> can only be used in C++17 and later."
  17. #endif
  18. #endif
  19. namespace boost::math::ccmath {
  20. namespace detail {
  21. template <typename ReturnType, typename Z>
  22. inline constexpr ReturnType div_impl(const Z x, const Z y) noexcept
  23. {
  24. // std::div_t/ldiv_t/lldiv_t/imaxdiv_t can be defined as either { Z quot; Z rem; }; or { Z rem; Z quot; };
  25. // so don't use braced initialization to guarantee compatibility
  26. ReturnType ans {0, 0};
  27. ans.quot = x / y;
  28. ans.rem = x % y;
  29. return ans;
  30. }
  31. } // Namespace detail
  32. // Used for types other than built-ins (e.g. boost multiprecision)
  33. template <typename Z>
  34. struct div_t
  35. {
  36. Z quot;
  37. Z rem;
  38. };
  39. template <typename Z>
  40. inline constexpr auto div(Z x, Z y) noexcept
  41. {
  42. if constexpr (std::is_same_v<Z, int>)
  43. {
  44. return detail::div_impl<std::div_t>(x, y);
  45. }
  46. else if constexpr (std::is_same_v<Z, long>)
  47. {
  48. return detail::div_impl<std::ldiv_t>(x, y);
  49. }
  50. else if constexpr (std::is_same_v<Z, long long>)
  51. {
  52. return detail::div_impl<std::lldiv_t>(x, y);
  53. }
  54. else if constexpr (std::is_same_v<Z, std::intmax_t>)
  55. {
  56. return detail::div_impl<std::imaxdiv_t>(x, y);
  57. }
  58. else
  59. {
  60. return detail::div_impl<boost::math::ccmath::div_t<Z>>(x, y);
  61. }
  62. }
  63. inline constexpr std::ldiv_t ldiv(long x, long y) noexcept
  64. {
  65. return detail::div_impl<std::ldiv_t>(x, y);
  66. }
  67. inline constexpr std::lldiv_t lldiv(long long x, long long y) noexcept
  68. {
  69. return detail::div_impl<std::lldiv_t>(x, y);
  70. }
  71. inline constexpr std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) noexcept
  72. {
  73. return detail::div_impl<std::imaxdiv_t>(x, y);
  74. }
  75. } // Namespaces
  76. #endif // BOOST_MATH_CCMATH_DIV_HPP