Skip to content
Open
Show file tree
Hide file tree
Changes from all 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__
#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 STREQUAL "Clang" AND NOT WIN32) OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "13" AND NOT WIN32))
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 STREQUAL "Clang" AND NOT WIN32) OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "13" AND NOT WIN32))
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;
}