87 lines · plain
1// (C) Copyright Matt Borland 2021.2// Use, modification and distribution are subject to the3// Boost Software License, Version 1.0. (See accompanying file4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)5 6#ifndef BOOST_MATH_CCMATH_DIV_HPP7#define BOOST_MATH_CCMATH_DIV_HPP8 9#include <cinttypes>10#include <cstdint>11#include <boost/math/ccmath/detail/config.hpp>12 13#ifdef BOOST_MATH_NO_CCMATH14#error "The header <boost/math/div.hpp> can only be used in C++17 and later."15#endif16 17namespace boost::math::ccmath {18 19namespace detail {20 21template <typename ReturnType, typename Z>22inline constexpr ReturnType div_impl(const Z x, const Z y) noexcept23{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 compatibility26 ReturnType ans {0, 0};27 28 ans.quot = x / y;29 ans.rem = x % y;30 31 return ans;32}33 34} // Namespace detail35 36// Used for types other than built-ins (e.g. boost multiprecision)37template <typename Z>38struct div_t39{40 Z quot;41 Z rem;42};43 44template <typename Z>45inline constexpr auto div(Z x, Z y) noexcept46{47 if constexpr (std::is_same_v<Z, int>)48 {49 return detail::div_impl<std::div_t>(x, y);50 }51 else if constexpr (std::is_same_v<Z, long>)52 {53 return detail::div_impl<std::ldiv_t>(x, y);54 }55 else if constexpr (std::is_same_v<Z, long long>)56 {57 return detail::div_impl<std::lldiv_t>(x, y);58 }59 else if constexpr (std::is_same_v<Z, std::intmax_t>)60 {61 return detail::div_impl<std::imaxdiv_t>(x, y);62 }63 else64 {65 return detail::div_impl<boost::math::ccmath::div_t<Z>>(x, y);66 }67}68 69inline constexpr std::ldiv_t ldiv(long x, long y) noexcept70{71 return detail::div_impl<std::ldiv_t>(x, y);72}73 74inline constexpr std::lldiv_t lldiv(long long x, long long y) noexcept75{76 return detail::div_impl<std::lldiv_t>(x, y);77}78 79inline constexpr std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) noexcept80{81 return detail::div_impl<std::imaxdiv_t>(x, y);82}83 84} // Namespaces85 86#endif // BOOST_MATH_CCMATH_DIV_HPP87