mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
constexpr div (#691)
This commit is contained in:
@@ -64,6 +64,12 @@ All of the following functions require C++17 or greater.
|
||||
template <typename Integer>
|
||||
inline constexpr double ldexp(Integer arg, int exp);
|
||||
|
||||
template <typename Integer>
|
||||
struct div_t {Integer quot; Integer rem;};
|
||||
|
||||
template <typename Integer>
|
||||
inline constexpr div_t<Integer> div(Integer x, Integer y);
|
||||
|
||||
} // Namespaces
|
||||
|
||||
[endsect] [/section:ccmath Constexpr CMath]
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_MATH_CCMATH
|
||||
#define BOOST_MATH_CCMATH
|
||||
#ifndef BOOST_MATH_CCMATH_HPP
|
||||
#define BOOST_MATH_CCMATH_HPP
|
||||
|
||||
#include <boost/math/ccmath/sqrt.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
@@ -16,5 +16,6 @@
|
||||
#include <boost/math/ccmath/isnormal.hpp>
|
||||
#include <boost/math/ccmath/fpclassify.hpp>
|
||||
#include <boost/math/ccmath/frexp.hpp>
|
||||
#include <boost/math/ccmath/div.hpp>
|
||||
|
||||
#endif // BOOST_MATH_CCMATH
|
||||
#endif // BOOST_MATH_CCMATH_HPP
|
||||
|
||||
84
include/boost/math/ccmath/div.hpp
Normal file
84
include/boost/math/ccmath/div.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
// (C) Copyright Matt Borland 2021.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_MATH_CCMATH_DIV_HPP
|
||||
#define BOOST_MATH_CCMATH_DIV_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename ReturnType, typename Z>
|
||||
inline constexpr ReturnType div_impl(const Z x, const Z y) noexcept
|
||||
{
|
||||
// std::div_t/ldiv_t/lldiv_t/imaxdiv_t can be defined as either { Z quot; Z rem; }; or { Z rem; Z quot; };
|
||||
// so don't use braced initialziation to guarantee compatibility
|
||||
ReturnType ans {0, 0};
|
||||
|
||||
ans.quot = x / y;
|
||||
ans.rem = x % y;
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
// Used for types other than built-ins (e.g. boost multiprecision)
|
||||
template <typename Z>
|
||||
struct div_t
|
||||
{
|
||||
Z quot;
|
||||
Z rem;
|
||||
};
|
||||
|
||||
template <typename Z>
|
||||
inline constexpr auto div(Z x, Z y) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<Z, int>)
|
||||
{
|
||||
return detail::div_impl<std::div_t>(x, y);
|
||||
}
|
||||
else if constexpr (std::is_same_v<Z, long>)
|
||||
{
|
||||
return detail::div_impl<std::ldiv_t>(x, y);
|
||||
}
|
||||
else if constexpr (std::is_same_v<Z, long long>)
|
||||
{
|
||||
return detail::div_impl<std::lldiv_t>(x, y);
|
||||
}
|
||||
else if constexpr (std::is_same_v<Z, std::intmax_t>)
|
||||
{
|
||||
return detail::div_impl<std::imaxdiv_t>(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return detail::div_impl<boost::math::ccmath::div_t<Z>>(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
inline constexpr std::ldiv_t ldiv(long x, long y) noexcept
|
||||
{
|
||||
return detail::div_impl<std::ldiv_t>(x, y);
|
||||
}
|
||||
|
||||
inline constexpr std::lldiv_t lldiv(long long x, long long y) noexcept
|
||||
{
|
||||
return detail::div_impl<std::lldiv_t>(x, y);
|
||||
}
|
||||
|
||||
inline constexpr std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) noexcept
|
||||
{
|
||||
return detail::div_impl<std::imaxdiv_t>(x, y);
|
||||
}
|
||||
|
||||
} // Namespaces
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_DIV_HPP
|
||||
@@ -130,6 +130,7 @@ test-suite special_fun :
|
||||
[ run ccmath_fpclassify_test.cpp ../../test/build//boost_unit_test_framework : : : [ requires cxx17_if_constexpr ] ]
|
||||
[ run ccmath_frexp_test.cpp ../../test/build//boost_unit_test_framework : : : [ requires cxx17_if_constexpr ] ]
|
||||
[ run ccmath_ldexp_test.cpp ../../test/build//boost_unit_test_framework : : : [ requires cxx17_if_constexpr ] ]
|
||||
[ run ccmath_div_test.cpp ../../test/build//boost_unit_test_framework : : : [ requires cxx17_if_constexpr ] ]
|
||||
[ run log1p_expm1_test.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
|
||||
[ run powm1_sqrtp1m1_test.cpp test_instances//test_instances pch_light ../../test/build//boost_unit_test_framework ]
|
||||
[ run special_functions_test.cpp ../../test/build//boost_unit_test_framework ]
|
||||
|
||||
47
test/ccmath_div_test.cpp
Normal file
47
test/ccmath_div_test.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// (C) Copyright Matt Borland 2021.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <cstdint>
|
||||
#include <cinttypes>
|
||||
#include <boost/math/ccmath/div.hpp>
|
||||
#include <boost/math/tools/is_constant_evaluated.hpp>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
template <typename Z>
|
||||
constexpr void test()
|
||||
{
|
||||
constexpr auto test_val1 = boost::math::ccmath::div(Z(1), Z(1));
|
||||
static_assert(test_val1.quot == Z(1));
|
||||
static_assert(test_val1.rem == Z(0));
|
||||
|
||||
constexpr auto test_val2 = boost::math::ccmath::div(Z(1'000'000), Z(3));
|
||||
static_assert(test_val2.quot == Z(333'333));
|
||||
static_assert(test_val2.rem == Z(1));
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MATH_NO_CONSTEXPR_DETECTION) && !defined(BOOST_MATH_USING_BUILTIN_CONSTANT_P)
|
||||
int main()
|
||||
{
|
||||
test<int>();
|
||||
test<long>();
|
||||
test<long long>();
|
||||
test<std::intmax_t>();
|
||||
|
||||
test<std::int32_t>();
|
||||
test<std::int64_t>();
|
||||
test<std::uint32_t>();
|
||||
|
||||
test<boost::multiprecision::int128_t>();
|
||||
test<boost::multiprecision::int256_t>();
|
||||
test<boost::multiprecision::int512_t>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
14
test/compile_test/ccmath_div_incl_test.cpp
Normal file
14
test/compile_test/ccmath_div_incl_test.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
// (C) Copyright Matt Borland 2021.
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/math/ccmath/div.hpp>
|
||||
#include "test_compile_result.hpp"
|
||||
|
||||
void compile_and_link_test()
|
||||
{
|
||||
check_result<std::div_t>(boost::math::ccmath::div(1, 1));
|
||||
check_result<std::ldiv_t>(boost::math::ccmath::div(1l, 1l));
|
||||
check_result<std::lldiv_t>(boost::math::ccmath::div(1ll, 1ll));
|
||||
}
|
||||
Reference in New Issue
Block a user