brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.0 KiB · 3639610 Raw
81 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//  Constexpr implementation of sqrt function7 8#ifndef BOOST_MATH_CCMATH_SQRT9#define BOOST_MATH_CCMATH_SQRT10 11#include <boost/math/ccmath/detail/config.hpp>12 13#ifdef BOOST_MATH_NO_CCMATH14#error "The header <boost/math/sqrt.hpp> can only be used in C++17 and later."15#endif16 17#include <boost/math/ccmath/abs.hpp>18#include <boost/math/ccmath/isnan.hpp>19#include <boost/math/ccmath/isinf.hpp>20#include <boost/math/tools/is_constant_evaluated.hpp>21 22namespace boost::math::ccmath { 23 24namespace detail {25 26template <typename Real>27constexpr Real sqrt_impl_2(Real x, Real s, Real s2)28{29    return !(s < s2) ? s2 : sqrt_impl_2(x, (x / s + s) / 2, s);30}31 32template <typename Real>33constexpr Real sqrt_impl_1(Real x, Real s)34{35    return sqrt_impl_2(x, (x / s + s) / 2, s);36}37 38template <typename Real>39constexpr Real sqrt_impl(Real x)40{41    return sqrt_impl_1(x, x > 1 ? x : Real(1));42}43 44} // namespace detail45 46template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, bool> = true>47constexpr Real sqrt(Real x)48{49    if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))50    {51        if (boost::math::ccmath::isnan(x) || 52           (boost::math::ccmath::isinf(x) && x > 0) ||53            boost::math::ccmath::abs(x) == Real(0))54        {55            return x;56        }57        // Domain error is implementation defined so return NAN58        else if (boost::math::ccmath::isinf(x) && x < 0)59        {60            return std::numeric_limits<Real>::quiet_NaN();61        }62 63        return detail::sqrt_impl<Real>(x);64    }65    else66    {67        using std::sqrt;68        return sqrt(x);69    }70}71 72template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>73constexpr double sqrt(Z x)74{75    return detail::sqrt_impl<double>(static_cast<double>(x));76}77 78} // Namespaces79 80#endif // BOOST_MATH_CCMATH_SQRT81