/** * See https://github.com/eddelbuettel/rcppfastfloat/issues/4 */ #include "fast_float/fast_float.h" #include #include #include struct test_data { std::string input; bool expected_success; double expected_result; }; bool eddelbuettel() { std::vector const test_datas = { {"infinity", true, std::numeric_limits::infinity()}, {" \r\n\t\f\v3.16227766016838 \r\n\t\f\v", true, 3.16227766016838}, {" \r\n\t\f\v3 \r\n\t\f\v", true, 3.0}, {" 1970-01-01", false, 0.0}, {"-NaN", true, std::numeric_limits::quiet_NaN()}, {"-inf", true, -std::numeric_limits::infinity()}, {" \r\n\t\f\v2.82842712474619 \r\n\t\f\v", true, 2.82842712474619}, {"nan", true, std::numeric_limits::quiet_NaN()}, {" \r\n\t\f\v2.44948974278318 \r\n\t\f\v", true, 2.44948974278318}, {"Inf", true, std::numeric_limits::infinity()}, {" \r\n\t\f\v2 \r\n\t\f\v", true, 2.0}, {"-infinity", true, -std::numeric_limits::infinity()}, {" \r\n\t\f\v0 \r\n\t\f\v", true, 0.0}, {" \r\n\t\f\v1.73205080756888 \r\n\t\f\v", true, 1.73205080756888}, {" \r\n\t\f\v1 \r\n\t\f\v", true, 1.0}, {" \r\n\t\f\v1.4142135623731 \r\n\t\f\v", true, 1.4142135623731}, {" \r\n\t\f\v2.23606797749979 \r\n\t\f\v", true, 2.23606797749979}, {"1970-01-02 ", false, 0.0}, {" \r\n\t\f\v2.64575131106459 \r\n\t\f\v", true, 2.64575131106459}, {"inf", true, std::numeric_limits::infinity()}, {"-nan", true, std::numeric_limits::quiet_NaN()}, {"NaN", true, std::numeric_limits::quiet_NaN()}, {"", false, 0.0}, {"-Inf", true, -std::numeric_limits::infinity()}, {"+2.2", true, 2.2}, {"1d+4", false, 0.0}, {"1d-1", false, 0.0}, {"0.", true, 0.0}, {"-.1", true, -0.1}, {"+.1", true, 0.1}, {"1e+1", true, 10.0}, {"+1e1", true, 10.0}, {"-+0", false, 0.0}, {"-+inf", false, 0.0}, {"-+nan", false, 0.0}, }; for (size_t i = 0; i < test_datas.size(); i++) { auto const &input = test_datas[i].input; auto const expected_success = test_datas[i].expected_success; auto const expected_result = test_datas[i].expected_result; double result; // answer contains a error code and a pointer to the end of the // parsed region (on success). auto const answer = fast_float::from_chars( input.data(), input.data() + input.size(), result, fast_float::chars_format::general | fast_float::chars_format::allow_leading_plus | fast_float::chars_format::skip_white_space); if (answer.ec != std::errc()) { std::cout << "could not parse" << std::endl; if (expected_success) { return false; } continue; } bool non_space_trailing_content = false; if (answer.ptr != input.data() + input.size()) { // check that there is no content left for (const char *leftover = answer.ptr; leftover != input.data() + input.size(); leftover++) { if (!fast_float::is_space(uint8_t(*leftover))) { non_space_trailing_content = true; break; } } } if (non_space_trailing_content) { std::cout << "found trailing content " << std::endl; if (!expected_success) { continue; } else { return false; } } std::cout << "parsed " << result << std::endl; if (!expected_success) { return false; } if (result != expected_result && !(std::isnan(result) && std::isnan(expected_result))) { std::cout << "results do not match. Expected " << expected_result << std::endl; return false; } } return true; } int main() { if (!eddelbuettel()) { printf("Bug.\n"); return EXIT_FAILURE; } printf("All ok.\n"); return EXIT_SUCCESS; }