fast_float/tests/example_test.cpp
2024-09-13 16:44:52 -04:00

159 lines
4.0 KiB
C++

#include "fast_float/fast_float.h"
#include <iostream>
#include <string>
#include <system_error>
bool many() {
const std::string 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() {
const std::string input = "234532.3426362,7869234.9823,324562.645";
double result;
const char *pointer = input.data();
const char *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;
}