// Unit test for boost::lexical_cast. // // See http://www.boost.org for most recent version, including documentation. // // Copyright Antony Polukhin, 2011-2019. // // Distributed under 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 #if defined(__INTEL_COMPILER) #pragma warning(disable: 193 383 488 981 1418 1419) #elif defined(BOOST_MSVC) #pragma warning(disable: 4097 4100 4121 4127 4146 4244 4245 4511 4512 4701 4800) #endif #include #include #include #include #include #include #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING) #define BOOST_LCAST_NO_WCHAR_T #endif using namespace boost; template bool is_pos_inf(T value) { return (boost::math::isinf)(value) && !(boost::math::signbit)(value); } template bool is_neg_inf(T value) { return (boost::math::isinf)(value) && (boost::math::signbit)(value); } template bool is_pos_nan(T value) { return (boost::math::isnan)(value) && !(boost::math::signbit)(value); } template bool is_neg_nan(T value) { /* There is some strange behaviour on Itanium platform with -nan nuber for long double. * It is a IA64 feature, or it is a boost::math feature, not a lexical_cast bug */ #if defined(__ia64__) || defined(_M_IA64) return (boost::math::isnan)(value) && ( boost::is_same::value || (boost::math::signbit)(value) ); #else return (boost::math::isnan)(value) && (boost::math::signbit)(value); #endif } template void test_inf_nan_templated() { typedef T test_t; BOOST_CHECK( is_pos_inf( lexical_cast("inf") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("INF") ) ); BOOST_CHECK( is_neg_inf( lexical_cast("-inf") ) ); BOOST_CHECK( is_neg_inf( lexical_cast("-INF") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("+inf") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("+INF") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("infinity") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("INFINITY") ) ); BOOST_CHECK( is_neg_inf( lexical_cast("-infinity") ) ); BOOST_CHECK( is_neg_inf( lexical_cast("-INFINITY") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("+infinity") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("+INFINITY") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("iNfiNity") ) ); BOOST_CHECK( is_pos_inf( lexical_cast("INfinity") ) ); BOOST_CHECK( is_neg_inf( lexical_cast("-inFINITY") ) ); BOOST_CHECK( is_neg_inf( lexical_cast("-INFINITY") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("nan") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("NAN") ) ); BOOST_CHECK( is_neg_nan( lexical_cast("-nan") ) ); BOOST_CHECK( is_neg_nan( lexical_cast("-NAN") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("+nan") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("+NAN") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("nAn") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("NaN") ) ); BOOST_CHECK( is_neg_nan( lexical_cast("-nAn") ) ); BOOST_CHECK( is_neg_nan( lexical_cast("-NaN") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("+Nan") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("+nAN") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("nan()") ) ); BOOST_CHECK( is_pos_nan( lexical_cast("NAN(some string)") ) ); BOOST_CHECK_THROW( lexical_cast("NAN(some string"), bad_lexical_cast ); BOOST_CHECK(lexical_cast( (boost::math::changesign)(std::numeric_limits::infinity())) == "-inf" ); BOOST_CHECK(lexical_cast( std::numeric_limits::infinity()) == "inf" ); BOOST_CHECK(lexical_cast( std::numeric_limits::quiet_NaN()) == "nan" ); #if !defined(__ia64__) && !defined(_M_IA64) BOOST_CHECK(lexical_cast( (boost::math::changesign)(std::numeric_limits::quiet_NaN())) == "-nan" ); #endif #ifndef BOOST_LCAST_NO_WCHAR_T BOOST_CHECK( is_pos_inf( lexical_cast(L"inf") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"INF") ) ); BOOST_CHECK( is_neg_inf( lexical_cast(L"-inf") ) ); BOOST_CHECK( is_neg_inf( lexical_cast(L"-INF") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"+inf") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"+INF") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"infinity") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"INFINITY") ) ); BOOST_CHECK( is_neg_inf( lexical_cast(L"-infinity") ) ); BOOST_CHECK( is_neg_inf( lexical_cast(L"-INFINITY") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"+infinity") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"+INFINITY") ) ); BOOST_CHECK( is_neg_inf( lexical_cast(L"-infINIty") ) ); BOOST_CHECK( is_neg_inf( lexical_cast(L"-INFiniTY") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"+inFINIty") ) ); BOOST_CHECK( is_pos_inf( lexical_cast(L"+INfinITY") ) ); BOOST_CHECK( is_pos_nan( lexical_cast(L"nan") ) ); BOOST_CHECK( is_pos_nan( lexical_cast(L"NAN") ) ); BOOST_CHECK( is_neg_nan( lexical_cast(L"-nan") ) ); BOOST_CHECK( is_neg_nan( lexical_cast(L"-NAN") ) ); BOOST_CHECK( is_pos_nan( lexical_cast(L"+nan") ) ); BOOST_CHECK( is_pos_nan( lexical_cast(L"+NAN") ) ); BOOST_CHECK( is_pos_nan( lexical_cast(L"nan()") ) ); BOOST_CHECK( is_pos_nan( lexical_cast(L"NAN(some string)") ) ); BOOST_CHECK_THROW( lexical_cast(L"NAN(some string"), bad_lexical_cast ); BOOST_CHECK(lexical_cast( (boost::math::changesign)(std::numeric_limits::infinity())) == L"-inf" ); BOOST_CHECK(lexical_cast( std::numeric_limits::infinity()) == L"inf" ); BOOST_CHECK(lexical_cast( std::numeric_limits::quiet_NaN()) == L"nan" ); #if !defined(__ia64__) && !defined(_M_IA64) BOOST_CHECK(lexical_cast( (boost::math::changesign)(std::numeric_limits::quiet_NaN())) == L"-nan" ); #endif #endif } void test_inf_nan_float() { test_inf_nan_templated(); } void test_inf_nan_double() { test_inf_nan_templated(); } void test_inf_nan_long_double() { // We do not run tests on compilers with bugs #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS test_inf_nan_templated(); #endif BOOST_CHECK(true); } unit_test::test_suite *init_unit_test_suite(int, char *[]) { unit_test::test_suite *suite = BOOST_TEST_SUITE("lexical_cast inf anf nan parsing unit test"); suite->add(BOOST_TEST_CASE(&test_inf_nan_float)); suite->add(BOOST_TEST_CASE(&test_inf_nan_double)); suite->add(BOOST_TEST_CASE(&test_inf_nan_long_double)); return suite; }