Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define C++20 concepts #848

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/boost/math/ccmath/abs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
#include <type_traits>
#include <limits>
#include <boost/math/tools/is_constant_evaluated.hpp>
#include <boost/math/concepts/concepts.hpp>
#include <boost/math/ccmath/isnan.hpp>
#include <boost/math/ccmath/isinf.hpp>

namespace boost::math::ccmath {

namespace detail {

template <typename T>
template <BOOST_MATH_ARITHMETIC T>
inline constexpr T abs_impl(T x) noexcept
{
return boost::math::ccmath::isnan(x) ? std::numeric_limits<T>::quiet_NaN() :
Expand All @@ -32,6 +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)
inline constexpr T abs(T x) noexcept
{
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
Expand All @@ -48,6 +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)
inline constexpr T abs(T x) noexcept
{
if constexpr (std::is_convertible_v<T, int>)
Expand Down
111 changes: 111 additions & 0 deletions include/boost/math/concepts/concepts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// (C) Copyright Matt Borland 2022.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_MATH_CONCEPTS_CONCEPTS_HPP
#define BOOST_MATH_CONCEPTS_CONCEPTS_HPP

#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L
#if __has_include(<concepts>)
#include <concepts>

#include <type_traits>
#include <boost/math/tools/config.hpp>

namespace boost::math::concepts {

template <typename T>
concept Integral = std::is_integral_v<T>
#ifdef __SIZEOF_INT128__
|| std::is_same_v<__int128_t, T>
|| std::is_same_v<__uint128_t, T>
#endif
;


template <typename T>
concept Signed_integral = std::is_integral_v<T> && std::is_signed_v<T>
#ifdef __SIZEOF_INT128__
|| std::is_same_v<__int128_t, T>
#endif
;

template <typename T>
concept Unsigned_integral = std::is_integral_v<T> && std::is_unsigned_v<T>
#ifdef __SIZEOF_INT128__
|| std::is_same_v<__uint128_t, T>
#endif
;

template <typename T>
concept Real = std::is_floating_point_v<T>
#ifdef BOOST_HAS_FLOAT128
|| std::is_same_v<__float128, T>
#endif
;

template <typename T>
concept Arithmetic = Integral<T> || Real<T>;

template <typename T>
concept Signed_arithmetic = Arithmetic<T> && (std::is_signed_v<T>
#ifdef __SIZEOF_INT128__
|| std::is_same_v<__int128_t, T>
#endif
);

template <typename T>
concept Unsigned_arithmetic = Arithmetic<T> && (std::is_unsigned_v<T>
#ifdef __SIZEOF_INT128__
|| std::is_same_v<__uint128_t, T>
#endif
);

}

#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_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_REQUIRES(X, T) requires X<T>

#endif
#endif

#ifndef BOOST_MATH_INTEGRAL
# define BOOST_MATH_INTEGRAL typename
#endif

#ifndef BOOST_MATH_SIGNED_INTEGRAL
# define BOOST_MATH_SIGNED_INTEGRAL typename
#endif

#ifndef BOOST_MATH_UNSIGNED_INTEGRAL
# define BOOST_MATH_UNSIGNED_INTEGRAL typename
#endif

#ifndef BOOST_MATH_REAL
# define BOOST_MATH_REAL typename
#endif

#ifndef BOOST_MATH_ARITHMETIC
# define BOOST_MATH_ARITHMETIC typename
#endif

#ifndef BOOST_MATH_SIGNED_ARITHMETIC
# define BOOST_MATH_SIGNED_ARITHMETIC typename
#endif

#ifndef BOOST_MATH_UNSIGNED_ARITHMETIC
# define BOOST_MATH_UNSIGNED_ARITHMETIC typename
#endif

#ifndef BOOST_MATH_REQUIRES
# define BOOST_MATH_REQUIRES(X, T)
#endif

#endif // BOOST_MATH_CONCEPTS_CONCEPTS_HPP
40 changes: 40 additions & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,46 @@ alias no_eh_tests :

explicit no_eh_tests ;

# alias for the ccmath tests

alias ccmath_tests :
ccmath_abs_test
ccmath_ceil_test
ccmath_copysign_test
ccmath_div_test
ccmath_fdim_test
ccmath_floor_test
ccmath_fma_test
ccmath_fmax_test
ccmath_fmin_test
ccmath_fmod_test
ccmath_fpclassify_test
ccmath_frexp_test
ccmath_hypot_test
ccmath_ilogb_test
ccmath_isfinite_test
ccmath_isgreater_test
ccmath_isgreaterequal_test
ccmath_isinf_test
ccmath_isless_test
ccmath_islessequal_test
ccmath_isnan_test
ccmath_isnormal_test
ccmath_isunordered_test
ccmath_ldexp_test
ccmath_logb_test
ccmath_modf_test
ccmath_next_test
ccmath_remainder_test
ccmath_round_test
ccmath_scalbln_test
ccmath_scalbn_test
ccmath_signbit_test
ccmath_sqrt_test
;

explicit ccmath_tests ;

# Some aliases which group blocks of tests for CI testing:

alias github_ci_block_1 : special_fun float128_tests distribution_tests mp misc ;
Expand Down