adding C interface without dep to C++ standard lib

This commit is contained in:
Daniel Lemire 2026-02-24 10:55:53 -05:00
parent 221a4920db
commit df5db2cfbf
5 changed files with 80 additions and 1 deletions

View File

@ -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)
@ -32,6 +32,8 @@ endif()
add_library(fast_float INTERFACE)
add_subdirectory(src)
option(FASTFLOAT_BENCHMARKS "Enable benchmarks" OFF)
if(FASTFLOAT_BENCHMARKS)

View File

@ -0,0 +1,32 @@
#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
src/CMakeLists.txt Normal file
View File

@ -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
src/fast_float_strtod.cpp Normal file
View File

@ -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;
}

View File

@ -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)