| #include "fast_float/fast_float.h" | |
| #include <iostream> | |
| #include <string> | |
| #include <system_error> | |
| bool many() { | |
| std::string const input = "234532.3426362,7869234.9823,324562.645"; | |
| double result; | |
| auto answer = | |
| fast_float::from_chars(input.data(), input.data() + input.size(), result); | |
| if (answer.ec != std::errc()) { | |
| return false; | |
| } | |
| if (result != 234532.3426362) { | |
| return false; | |
| } | |
| if (answer.ptr[0] != ',') { | |
| return false; | |
| } | |
| answer = fast_float::from_chars(answer.ptr + 1, input.data() + input.size(), | |
| result); | |
| if (answer.ec != std::errc()) { | |
| return false; | |
| } | |
| if (result != 7869234.9823) { | |
| return false; | |
| } | |
| if (answer.ptr[0] != ',') { | |
| return false; | |
| } | |
| answer = fast_float::from_chars(answer.ptr + 1, input.data() + input.size(), | |
| result); | |
| if (answer.ec != std::errc()) { | |
| return false; | |
| } | |
| if (result != 324562.645) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| void many_loop() { | |
| std::string const input = "234532.3426362,7869234.9823,324562.645"; | |
| double result; | |
| char const *pointer = input.data(); | |
| char const *end_pointer = input.data() + input.size(); | |
| while (pointer < end_pointer) { | |
| auto answer = fast_float::from_chars(pointer, end_pointer, result); | |
| if (answer.ec != std::errc()) { | |
| std::cerr << "error while parsing" << std::endl; | |
| break; | |
| } | |
| std::cout << "parsed: " << result << std::endl; | |
| pointer = answer.ptr; | |
| if ((answer.ptr < end_pointer) && (*pointer == ',')) { | |
| pointer++; | |
| } | |
| } | |
| } | |
| #if FASTFLOAT_IS_CONSTEXPR | |
| // consteval forces compile-time evaluation of the function in C++20. | |
| consteval double parse(std::string_view input) { | |
| double result; | |
| auto answer = | |
| fast_float::from_chars(input.data(), input.data() + input.size(), result); | |
| if (answer.ec != std::errc()) { | |
| return -1.0; | |
| } | |
| return result; | |
| } | |
| // This function should compile to a function which | |
| // merely returns 3.1415. | |
| constexpr double constexptest() { return parse("3.1415 input"); } | |
| #endif | |
| bool small() { | |
| double result = -1; | |
| std::string str = "3e-1000"; | |
| auto r = fast_float::from_chars(str.data(), str.data() + str.size(), result); | |
| if (r.ec != std::errc::result_out_of_range) { | |
| return false; | |
| } | |
| if (r.ptr != str.data() + 7) { | |
| return false; | |
| } | |
| if (result != 0) { | |
| return false; | |
| } | |
| printf("small values go to zero\n"); | |
| return true; | |
| } | |
| bool large() { | |
| double result = -1; | |
| std::string str = "3e1000"; | |
| auto r = fast_float::from_chars(str.data(), str.data() + str.size(), result); | |
| if (r.ec != std::errc::result_out_of_range) { | |
| return false; | |
| } | |
| if (r.ptr != str.data() + 6) { | |
| return false; | |
| } | |
| if (result != std::numeric_limits<double>::infinity()) { | |
| return false; | |
| } | |
| printf("large values go to infinity\n"); | |
| return true; | |
| } | |
| int main() { | |
| std::string input = "3.1416 xyz "; | |
| double result; | |
| auto answer = | |
| fast_float::from_chars(input.data(), input.data() + input.size(), result); | |
| if ((answer.ec != std::errc()) || ((result != 3.1416))) { | |
| std::cerr << "parsing failure\n"; | |
| return EXIT_FAILURE; | |
| } | |
| std::cout << "parsed the number " << result << std::endl; | |
| #ifdef __STDCPP_FLOAT16_T__ | |
| printf("16-bit float\n"); | |
| // Parse as 16-bit float | |
| std::float16_t parsed_16{}; | |
| input = "10000e-1452"; | |
| auto fast_float_r16 = fast_float::from_chars( | |
| input.data(), input.data() + input.size(), parsed_16); | |
| if (fast_float_r16.ec != std::errc() && | |
| fast_float_r16.ec != std::errc::result_out_of_range) { | |
| std::cerr << "16-bit fast_float parsing failure for: " + input + "\n"; | |
| return false; | |
| } | |
| std::cout << "parsed the 16-bit value " << float(parsed_16) << std::endl; | |
| #endif | |
| if (!small()) { | |
| printf("Bug\n"); | |
| return EXIT_FAILURE; | |
| } | |
| if (!large()) { | |
| printf("Bug\n"); | |
| return EXIT_FAILURE; | |
| } | |
| if (!many()) { | |
| printf("Bug\n"); | |
| return EXIT_FAILURE; | |
| } | |
| many_loop(); | |
| #if FASTFLOAT_IS_CONSTEXPR | |
| if constexpr (constexptest() != 3.1415) { | |
| return EXIT_FAILURE; | |
| } | |
| #endif | |
| return EXIT_SUCCESS; | |
| } |