mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Add arbitrary arithmetic concepts
[ci skip]
This commit is contained in:
@@ -20,7 +20,7 @@ namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <BOOST_MATH_ARITHMETIC T>
|
||||
template <BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC T>
|
||||
inline constexpr T abs_impl(T x) noexcept
|
||||
{
|
||||
return boost::math::ccmath::isnan(x) ? std::numeric_limits<T>::quiet_NaN() :
|
||||
@@ -33,7 +33,7 @@ inline constexpr T abs_impl(T x) noexcept
|
||||
} // Namespace detail
|
||||
|
||||
template <typename T, std::enable_if_t<!std::is_unsigned_v<T>, bool> = true>
|
||||
BOOST_MATH_REQUIRES(BOOST_MATH_SIGNED_ARITHMETIC, T)
|
||||
BOOST_MATH_REQUIRES(BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC, T)
|
||||
inline constexpr T abs(T x) noexcept
|
||||
{
|
||||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
@@ -50,7 +50,7 @@ inline constexpr T abs(T x) noexcept
|
||||
// If abs() is called with an argument of type X for which is_unsigned_v<X> is true and if X
|
||||
// cannot be converted to int by integral promotion (7.3.7), the program is ill-formed.
|
||||
template <typename T, std::enable_if_t<std::is_unsigned_v<T>, bool> = true>
|
||||
BOOST_MATH_REQUIRES(BOOST_MATH_UNSIGNED_ARITHMETIC, T)
|
||||
BOOST_MATH_REQUIRES(BOOST_MATH_ARBITRARY_UNSIGNED_ARITHMETIC, T)
|
||||
inline constexpr T abs(T x) noexcept
|
||||
{
|
||||
if constexpr (std::is_convertible_v<T, int>)
|
||||
|
||||
@@ -6,15 +6,39 @@
|
||||
#ifndef BOOST_MATH_CONCEPTS_CONCEPTS_HPP
|
||||
#define BOOST_MATH_CONCEPTS_CONCEPTS_HPP
|
||||
|
||||
#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L
|
||||
#if (__cplusplus >= 202002L || _MSVC_LANG >= 202002L) && !defined(BOOST_MATH_DISABLE_CONCEPTS)
|
||||
#if __has_include(<concepts>)
|
||||
#include <concepts>
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/concepts/real_type_concept.hpp>
|
||||
|
||||
namespace boost::math::concepts {
|
||||
|
||||
template <typename X, typename Y, typename Op>
|
||||
struct op_valid_impl
|
||||
{
|
||||
template <typename U, typename L, typename R>
|
||||
static constexpr auto test(int) -> decltype(std::declval<U>()(std::declval<L>(), std::declval<R>()),
|
||||
void(), std::true_type());
|
||||
|
||||
template <typename U, typename L, typename R>
|
||||
static constexpr auto test(...) -> std::false_type;
|
||||
|
||||
using type = decltype(test<Op, X, Y>(0));
|
||||
};
|
||||
|
||||
template <typename X, typename Y, typename Op>
|
||||
using op_valid = typename op_valid_impl<X, Y, Op>::type;
|
||||
|
||||
template <typename X, typename Y, typename Op>
|
||||
inline constexpr bool op_valid_v = op_valid<X, Y, Op>::value;
|
||||
|
||||
template <typename T>
|
||||
concept Integral = std::is_integral_v<T>
|
||||
#ifdef __SIZEOF_INT128__
|
||||
@@ -66,15 +90,56 @@ concept Unsigned_arithmetic = Arithmetic<T> && (std::is_unsigned_v<T>
|
||||
#endif
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
concept Arbitrary_unsigned_arithmetic_type = Unsigned_arithmetic<T> ||
|
||||
(op_valid_v<T, T, std::equal_to<>> &&
|
||||
op_valid_v<T, T, std::not_equal_to<>> &&
|
||||
op_valid_v<T, T, std::greater<>> &&
|
||||
op_valid_v<T, T, std::less<>> &&
|
||||
op_valid_v<T, T, std::greater_equal<>> &&
|
||||
op_valid_v<T, T, std::less_equal<>> &&
|
||||
op_valid_v<T, T, std::plus<>> &&
|
||||
op_valid_v<T, T, std::minus<>> &&
|
||||
op_valid_v<T, T, std::multiplies<>> &&
|
||||
op_valid_v<T, T, std::divides<>> &&
|
||||
op_valid_v<T, T, std::modulus<>>);
|
||||
|
||||
template <typename T>
|
||||
concept Arbitrary_signed_arithmetic_type = Signed_arithmetic<T> ||
|
||||
(Arbitrary_unsigned_arithmetic_type<T> &&
|
||||
op_valid_v<T, T, std::negate<>>);
|
||||
|
||||
template <typename T>
|
||||
concept Arbitrary_arithmetic_type = Arbitrary_unsigned_arithmetic_type<T> ||
|
||||
Arbitrary_signed_arithmetic_type<T>;
|
||||
|
||||
template <typename T>
|
||||
concept Aribitrary_unsigned_integer_type = Arbitrary_unsigned_arithmetic_type<T> &&
|
||||
std::numeric_limits<T>::is_integer;
|
||||
|
||||
template <typename T>
|
||||
concept Aribitrary_signed_integer_type = Arbitrary_signed_arithmetic_type<T> &&
|
||||
std::numeric_limits<T>::is_integer;
|
||||
|
||||
template <typename T>
|
||||
concept Aribitrary_integer_type = Aribitrary_unsigned_integer_type<T> ||
|
||||
Aribitrary_signed_integer_type<T>;
|
||||
|
||||
}
|
||||
|
||||
#define BOOST_MATH_INTEGRAL boost::math::concepts::Integral<T>
|
||||
#define BOOST_MATH_SIGNED_INTEGRAL boost::math::concepts::Signed_integral<T>
|
||||
#define BOOST_MATH_UNSIGNED_INTEGRAL boost::math::concepts::Unsigned_integral<T>
|
||||
#define BOOST_MATH_INTEGRAL boost::math::concepts::Integral
|
||||
#define BOOST_MATH_SIGNED_INTEGRAL boost::math::concepts::Signed_integral
|
||||
#define BOOST_MATH_UNSIGNED_INTEGRAL boost::math::concepts::Unsigned_integral
|
||||
#define BOOST_MATH_REAL boost::math::concepts::Real
|
||||
#define BOOST_MATH_ARITHMETIC boost::math::concepts::Arithmetic
|
||||
#define BOOST_MATH_SIGNED_ARITHMETIC boost::math::concepts::Signed_arithmetic
|
||||
#define BOOST_MATH_UNSIGNED_ARITHMETIC boost::math::concepts::Unsigned_arithmetic
|
||||
#define BOOST_MATH_ARBITRARY_UNSIGNED_ARITHMETIC boost::math::concepts::Arbitrary_unsigned_arithmetic_type
|
||||
#define BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC boost::math::concepts::Arbitrary_signed_arithmetic_type
|
||||
#define BOOST_MATH_ARBITRARY_ARITHMETIC boost::math::concepts::Arbitrary_arithmetic_type
|
||||
#define BOOST_MATH_ARBITRARY_UNSIGNED_INTEGER boost::math::concepts::Aribitrary_unsigned_integer_type
|
||||
#define BOOST_MATH_ARBITRARY_SIGNED_INTEGER boost::math::concepts::Aribitrary_signed_integer_type
|
||||
#define BOOST_MATH_ARBITRARY_INTEGER boost::math::concepts::Aribitrary_integer_type
|
||||
#define BOOST_MATH_REQUIRES(X, T) requires X<T>
|
||||
|
||||
#endif
|
||||
@@ -108,6 +173,30 @@ concept Unsigned_arithmetic = Arithmetic<T> && (std::is_unsigned_v<T>
|
||||
# define BOOST_MATH_UNSIGNED_ARITHMETIC typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_ARBITRARY_UNSIGNED_ARITHMETIC
|
||||
# define BOOST_MATH_ARBITRARY_UNSIGNED_ARITHMETIC typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC
|
||||
# define BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_ARBITRARY_ARITHMETIC
|
||||
# define BOOST_MATH_ARBITRARY_ARITHMETIC typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_ARBITRARY_UNSIGNED_INTEGER
|
||||
# define BOOST_MATH_ARBITRARY_UNSIGNED_INTEGER typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_ARBITRARY_SIGNED_INTEGER
|
||||
# define BOOST_MATH_ARBITRARY_SIGNED_INTEGER typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_ARBITRARY_INTEGER
|
||||
# define BOOST_MATH_ARBITRARY_INTEGER typename
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MATH_REQUIRES
|
||||
# define BOOST_MATH_REQUIRES(X, T)
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user