/** * See https://github.com/eddelbuettel/rcppfastfloat/issues/4 */ #define FASTFLOAT_ALLOWS_LEADING_PLUS 1 #define FASTFLOAT_SKIP_WHITE_SPACE 1 // important ! #include "fast_float/fast_float.h" #include #include #include bool eddelbuettel() { std::vector inputs = {"infinity", " \r\n\t\f\v3.16227766016838 \r\n\t\f\v", " \r\n\t\f\v3 \r\n\t\f\v", " 1970-01-01", "-NaN", "-inf", " \r\n\t\f\v2.82842712474619 \r\n\t\f\v", "nan", " \r\n\t\f\v2.44948974278318 \r\n\t\f\v", "Inf", " \r\n\t\f\v2 \r\n\t\f\v", "-infinity", " \r\n\t\f\v0 \r\n\t\f\v", " \r\n\t\f\v1.73205080756888 \r\n\t\f\v", " \r\n\t\f\v1 \r\n\t\f\v", " \r\n\t\f\v1.4142135623731 \r\n\t\f\v", " \r\n\t\f\v2.23606797749979 \r\n\t\f\v", "1970-01-02 ", " \r\n\t\f\v2.64575131106459 \r\n\t\f\v", "inf", "-nan", "NaN", "", "-Inf", "+2.2", "1d+4", "1d-1", "0.", "-.1", "+.1", "1e+1", "+1e1"}; std::vector> expected_results = { {true, std::numeric_limits::infinity()}, {true, 3.16227766016838}, {true, 3}, {false, -1}, {true, std::numeric_limits::quiet_NaN()}, {true, -std::numeric_limits::infinity()}, {true, 2.82842712474619}, {true, std::numeric_limits::quiet_NaN()}, {true, 2.44948974278318}, {true, std::numeric_limits::infinity()}, {true, 2}, {true, -std::numeric_limits::infinity()}, {true, 0}, {true, 1.73205080756888}, {true, 1}, {true, 1.4142135623731}, {true, 2.23606797749979}, {false, -1}, {true, 2.64575131106459}, {true, std::numeric_limits::infinity()}, {true, std::numeric_limits::quiet_NaN()}, {true, std::numeric_limits::quiet_NaN()}, {false, -1}, {true, -std::numeric_limits::infinity()}, {true, 2.2}, {false, -1}, {false, -1}, {true, 0}, {true, -0.1}, {true, 0.1}, {true, 10}, {true, 10}, }; for (size_t i = 0; i < inputs.size(); i++) { const std::string &input = inputs[i]; std::pair expected = expected_results[i]; double result; // answer contains a error code and a pointer to the end of the // parsed region (on success). auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result); if (answer.ec != std::errc()) { std::cout << "could not parse" << std::endl; if (expected.first) { 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 (non_space_trailing_content) { if (!expected.first) { continue; } else { return false; } } std::cout << "parsed " << result << std::endl; if (!expected.first) { return false; } if (result != expected.second) { if (std::isnan(result) && std::isnan(expected.second)) { continue; } std::cout << "results do not match. Expected " << expected.second << std::endl; return false; } } return true; } int main() { if (!eddelbuettel()) { printf("Bug.\n"); return EXIT_FAILURE; } printf("All ok.\n"); return EXIT_SUCCESS; }