Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)


project(fast_float VERSION 8.2.3 LANGUAGES CXX)
project(fast_float VERSION 8.2.3 LANGUAGES CXX C)
set(FASTFLOAT_CXX_STANDARD 11 CACHE STRING "the C++ standard to use for fastfloat")
set(CMAKE_CXX_STANDARD ${FASTFLOAT_CXX_STANDARD})
option(FASTFLOAT_TEST "Enable tests" OFF)
Expand Down Expand Up @@ -32,6 +32,8 @@ endif()

add_library(fast_float INTERFACE)

add_subdirectory(src)


option(FASTFLOAT_BENCHMARKS "Enable benchmarks" OFF)
if(FASTFLOAT_BENCHMARKS)
Expand Down
31 changes: 31 additions & 0 deletions include/fast_float/fast_float_strtod.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef __FAST_FLOAT_STRTOD_H__
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include guards with double underscores are bad habits, this is a reserved name so has undefined behaviour! FAST_FLOAT_STRTOD_H would make a fine include guard :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I will fix this. Note that this is experimental and I will not be merging this PR immediately before it has received considerable review from others.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To give some more constructive feedback, this does seem like a useful addition.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!!! Much appreciated. You have increased the probability that we will move forward ! ah ah

#define __FAST_FLOAT_STRTOD_H__

#if defined(__cplusplus)
extern "C" {
#endif
/**
* @brief Convert a string to a double using the fast_float library. This is
* a C-compatible wrapper around the fast_float parsing functionality, designed
* to mimic the behavior of the standard strtod function.
*
* This function parses the initial portion of the null-terminated string `nptr`
* and converts it to a `double`, similar to the standard `strtod` function but
* utilizing the high-performance fast_float library for parsing.
*
* On successful conversion, the result is returned. If parsing fails, errno is
* set to EINVAL and 0.0 is returned.
*
* @param nptr Pointer to the null-terminated string to be parsed.
* @param endptr If not NULL, a pointer to store the address of the first
* character after the parsed number. If parsing fails, it points
* to the beginning of the string.
* @return The converted double value on success, or 0.0 on failure.
*/
double fast_float_strtod(const char *in, char **out);

#if defined(__cplusplus)
}
#endif

#endif /* __FAST_FLOAT_STRTOD_H__ */
14 changes: 14 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_library(fast_float_strtod STATIC fast_float_strtod.cpp)
target_link_libraries(fast_float_strtod PRIVATE fast_float)

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_link_options(fast_float_strtod PRIVATE -nostdlib++)
endif()

add_library(FastFloat::fast_float_strtod ALIAS fast_float_strtod)
target_include_directories(
fast_float_strtod
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
24 changes: 24 additions & 0 deletions src/fast_float_strtod.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "fast_float/fast_float_strtod.h"
#include "fast_float/fast_float.h"
#include <cerrno>
#include <cstring>
#include <system_error>

extern "C" double fast_float_strtod(const char *nptr, char **endptr) {
double result = 0.0;

// Parse the string using fast_float's from_chars function
auto parse_result = fast_float::from_chars(nptr, nptr + strlen(nptr), result);

// Check if parsing encountered an error
if (parse_result.ec != std::errc{}) {
errno = EINVAL;
}

// Update endptr if provided
if (endptr != nullptr) {
*endptr = const_cast<char *>(parse_result.ptr);
}

return result;
}
7 changes: 7 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,10 @@ endif(FASTFLOAT_EXHAUSTIVE)

add_subdirectory(build_tests)
add_subdirectory(bloat_analysis)

add_executable(strtod_test strtod_test.c)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
target_link_options(strtod_test PUBLIC -nostdlib++)
endif()
target_link_libraries(strtod_test PUBLIC fast_float_strtod)
add_test(NAME strtod_test COMMAND strtod_test)
28 changes: 28 additions & 0 deletions tests/strtod_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "fast_float/fast_float_strtod.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
// Test successful conversion
const char *str1 = "3.14159";
char *end1;
errno = 0;
double d1 = fast_float_strtod(str1, &end1);
printf("Input: %s\n", str1);
printf("Converted: %f\n", d1);
printf("End pointer: %s\n", end1);
printf("errno: %d\n", errno);

// Test invalid input
const char *str2 = "invalid";
char *end2;
errno = 0;
double d2 = fast_float_strtod(str2, &end2);
printf("\nInput: %s\n", str2);
printf("Converted: %f\n", d2);
printf("End pointer: %s\n", end2);
printf("errno: %d\n", errno);

return 0;
}
Loading