#include <iostream>
#include <iomanip>
#include <cmath> // for std::isnan
-#include <boost/assert.hpp>
+#include <string>
+#include <boost/math/tools/assert.hpp>
#include <boost/math/special_functions/next.hpp>
#include <boost/math/special_functions/trunc.hpp>
-#include <boost/core/demangle.hpp>
-
+#if defined __has_include
+# if __has_include(<cxxabi.h>)
+#define BOOST_MATH_HAS_CXX_ABI 1
+# include <cxxabi.h>
+# endif
+#endif
namespace boost { namespace math { namespace test {
namespace detail {
static std::atomic<int64_t> global_error_count{0};
static std::atomic<int64_t> total_ulp_distance{0};
+
+ inline std::string demangle(char const * name)
+ {
+ int status = 0;
+ std::size_t size = 0;
+#if BOOST_MATH_HAS_CXX_ABI
+ std::string s {abi::__cxa_demangle( name, NULL, &size, &status )};
+#else
+ std::string s {name};
+#endif
+ return s;
+ }
}
template<class Real>
bool check_mollified_close(Real expected, Real computed, Real tol, std::string const & filename, std::string const & function, int line)
{
using std::isnan;
- BOOST_ASSERT_MSG(!isnan(tol), "Tolerance cannot be a nan.");
- BOOST_ASSERT_MSG(!isnan(expected), "Expected value cannot be a nan.");
- BOOST_ASSERT_MSG(tol >= 0, "Tolerance must be non-negative.");
+ BOOST_MATH_ASSERT_MSG(!isnan(tol), "Tolerance cannot be a nan.");
+ BOOST_MATH_ASSERT_MSG(!isnan(expected), "Expected value cannot be a nan.");
+ BOOST_MATH_ASSERT_MSG(tol >= 0, "Tolerance must be non-negative.");
if (isnan(computed)) {
std::ios_base::fmtflags f( std::cerr.flags() );
std::cerr << std::setprecision(3);
std::ios_base::fmtflags f( std::cerr.flags() );
std::cerr << std::setprecision(3);
std::cerr << "\033[0;31mError at " << filename << ":" << function << ":" << line << ":\n"
- << " \033[0m Mollified relative error in " << boost::core::demangle(typeid(Real).name())<< " precision is " << mollified_relative_error
+ << " \033[0m Mollified relative error in " << detail::demangle(typeid(Real).name())<< " precision is " << mollified_relative_error
<< ", which exceeds " << tol << ", error/tol = " << mollified_relative_error/tol << ".\n"
<< std::setprecision(std::numeric_limits<Real>::max_digits10) << std::showpos
<< " Expected: " << std::defaultfloat << std::fixed << expected << std::hexfloat << " = " << expected << "\n"
using boost::math::lltrunc;
// Of course integers can be expected values, and they are exact:
if (!std::is_integral<PreciseReal>::value) {
- BOOST_ASSERT_MSG(!isnan(expected1), "Expected value cannot be a nan.");
+ BOOST_MATH_ASSERT_MSG(!isnan(expected1), "Expected value cannot be a nan.");
if (sizeof(PreciseReal) < sizeof(Real)) {
std::ostringstream err;
err << "\n\tThe expected number must be computed in higher (or equal) precision than the number being tested.\n";
- err << "\tType of expected is " << boost::core::demangle(typeid(PreciseReal).name()) << ", which occupies " << sizeof(PreciseReal) << " bytes.\n";
- err << "\tType of computed is " << boost::core::demangle(typeid(Real).name()) << ", which occupies " << sizeof(Real) << " bytes.\n";
+ err << "\tType of expected is " << detail::demangle(typeid(PreciseReal).name()) << ", which occupies " << sizeof(PreciseReal) << " bytes.\n";
+ err << "\tType of computed is " << detail::demangle(typeid(Real).name()) << ", which occupies " << sizeof(Real) << " bytes.\n";
throw std::logic_error(err.str());
}
}
std::ios_base::fmtflags f( std::cerr.flags() );
std::cerr << std::setprecision(3);
std::cerr << "\033[0;31mError at " << filename << ":" << function << ":" << line << ":\n"
- << " \033[0m ULP distance in " << boost::core::demangle(typeid(Real).name())<< " precision is " << dist
+ << " \033[0m ULP distance in " << detail::demangle(typeid(Real).name())<< " precision is " << dist
<< ", which exceeds " << ulps;
if (ulps > 0)
{
std::ios_base::fmtflags f( std::cerr.flags() );
std::cerr << std::setprecision(3);
std::cerr << "\033[0;31mError at " << filename << ":" << function << ":" << line << ":\n"
- << " \033[0m Condition " << lesser << " \u2264 " << greater << " is violated in " << boost::core::demangle(typeid(Real).name()) << " precision.\n";
+ << " \033[0m Condition " << lesser << " \u2264 " << greater << " is violated in " << detail::demangle(typeid(Real).name()) << " precision.\n";
std::cerr << std::setprecision(std::numeric_limits<Real>::max_digits10) << std::showpos
<< " \"Lesser\" : " << std::defaultfloat << std::fixed << lesser << " = " << std::scientific << lesser << std::hexfloat << " = " << lesser << "\n"
<< " \"Greater\": " << std::defaultfloat << std::fixed << greater << " = " << std::scientific << greater << std::hexfloat << " = " << greater << "\n"
using std::isnan;
// Of course integers can be expected values, and they are exact:
if (!std::is_integral<PreciseReal>::value) {
- BOOST_ASSERT_MSG(sizeof(PreciseReal) >= sizeof(Real),
+ BOOST_MATH_ASSERT_MSG(sizeof(PreciseReal) >= sizeof(Real),
"The expected number must be computed in higher (or equal) precision than the number being tested.");
- BOOST_ASSERT_MSG(!isnan(abscissa), "Expected abscissa cannot be a nan.");
- BOOST_ASSERT_MSG(!isnan(expected1), "Expected value cannot be a nan.");
- BOOST_ASSERT_MSG(!isnan(expected_derivative), "Expected derivative cannot be a nan.");
+ BOOST_MATH_ASSERT_MSG(!isnan(abscissa), "Expected abscissa cannot be a nan.");
+ BOOST_MATH_ASSERT_MSG(!isnan(expected1), "Expected value cannot be a nan.");
+ BOOST_MATH_ASSERT_MSG(!isnan(expected_derivative), "Expected derivative cannot be a nan.");
}
- BOOST_ASSERT_MSG(acceptable_badness >= 1, "Acceptable badness scale must be >= 1, and in general should = 1 exactly.");
+ BOOST_MATH_ASSERT_MSG(acceptable_badness >= 1, "Acceptable badness scale must be >= 1, and in general should = 1 exactly.");
if (isnan(computed))
{
std::cerr << "\033[0;31mError at " << filename << ":" << function << ":" << line << ":\n";
std::cerr << std::setprecision(std::numeric_limits<Real>::max_digits10) << std::showpos;
std::cerr << "\033[0m Error at abscissa " << std::defaultfloat << std::fixed << abscissa << " = " << std::hexfloat << abscissa << "\n";
- std::cerr << " Given that the expected value is zero, the computed value in " << boost::core::demangle(typeid(Real).name()) << " precision must satisfy |f(x)| <= " << tol << ".\n";
+ std::cerr << " Given that the expected value is zero, the computed value in " << detail::demangle(typeid(Real).name()) << " precision must satisfy |f(x)| <= " << tol << ".\n";
std::cerr << " But the computed value is " << std::defaultfloat << std::fixed << computed << std::hexfloat << " = " << computed << "\n";
std::cerr.flags(f);
++detail::global_error_count;
std::cerr << "\033[0;31mError at " << filename << ":" << function << ":" << line << "\n";
std::cerr << std::setprecision(std::numeric_limits<Real>::max_digits10);
std::cerr << "\033[0m The relative error at abscissa x = " << std::defaultfloat << std::fixed << abscissa << " = " << std::hexfloat << abscissa
- << " in " << boost::core::demangle(typeid(Real).name()) << " precision is " << std::scientific << relative_error << "\n"
+ << " in " << detail::demangle(typeid(Real).name()) << " precision is " << std::scientific << relative_error << "\n"
<< " This exceeds the tolerance " << tol << "\n"
<< std::showpos
<< " Expected: " << std::defaultfloat << std::fixed << expected << " = " << std::scientific << expected << std::hexfloat << " = " << expected << "\n"
using std::isnan;
// Of course integers can be expected values, and they are exact:
if (!std::is_integral<PreciseReal>::value) {
- BOOST_ASSERT_MSG(sizeof(PreciseReal) >= sizeof(Real),
+ BOOST_MATH_ASSERT_MSG(sizeof(PreciseReal) >= sizeof(Real),
"The expected number must be computed in higher (or equal) precision than the number being tested.");
- BOOST_ASSERT_MSG(!isnan(expected1), "Expected value cannot be a nan (use CHECK_NAN if this is your intention).");
+ BOOST_MATH_ASSERT_MSG(!isnan(expected1), "Expected value cannot be a nan (use CHECK_NAN if this is your intention).");
}
- BOOST_ASSERT_MSG(acceptable_error > 0, "Error must be > 0.");
+ BOOST_MATH_ASSERT_MSG(acceptable_error > 0, "Error must be > 0.");
if (isnan(computed))
{
std::cerr << std::setprecision(3);
std::cerr << "\033[0;31mError at " << filename << ":" << function << ":" << line << "\n";
std::cerr << std::setprecision(std::numeric_limits<Real>::max_digits10);
- std::cerr << "\033[0m The absolute error in " << boost::core::demangle(typeid(Real).name()) << " precision is " << std::scientific << error << "\n"
+ std::cerr << "\033[0m The absolute error in " << detail::demangle(typeid(Real).name()) << " precision is " << std::scientific << error << "\n"
<< " This exceeds the acceptable error " << acceptable_error << "\n"
<< std::showpos
<< " Expected: " << std::defaultfloat << std::fixed << expected << " = " << std::scientific << expected << std::hexfloat << " = " << expected << "\n"