mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Merge pull request #5 from lemire/dlemire/improving_portability
This branch improves portability (under Windows).
This commit is contained in:
commit
0cb4aa175b
27
.github/workflows/alpine.yml
vendored
Normal file
27
.github/workflows/alpine.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: Alpine Linux
|
||||
'on':
|
||||
- push
|
||||
- pull_request
|
||||
jobs:
|
||||
ubuntu-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: start docker
|
||||
run: |
|
||||
docker run -w /src -dit --name alpine -v $PWD:/src alpine:latest
|
||||
echo 'docker exec alpine "$@";' > ./alpine.sh
|
||||
chmod +x ./alpine.sh
|
||||
- name: install packages
|
||||
run: |
|
||||
./alpine.sh apk update
|
||||
./alpine.sh apk add build-base cmake g++ linux-headers git bash
|
||||
- name: cmake
|
||||
run: |
|
||||
./alpine.sh cmake -DFASTFLOAT_TEST=ON -B build_for_alpine
|
||||
- name: build
|
||||
run: |
|
||||
./alpine.sh cmake --build build_for_alpine
|
||||
- name: test
|
||||
run: |
|
||||
./alpine.sh bash -c "cd build_for_alpine && ctest -R basictest"
|
||||
44
.github/workflows/msys2.yml
vendored
Normal file
44
.github/workflows/msys2.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
name: MSYS2-CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
windows-mingw:
|
||||
name: ${{ matrix.msystem }}
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- msystem: "MINGW64"
|
||||
install: mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-gcc
|
||||
type: Release
|
||||
- msystem: "MINGW32"
|
||||
install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-gcc
|
||||
type: Release
|
||||
- msystem: "MINGW64"
|
||||
install: mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-gcc
|
||||
type: Debug
|
||||
- msystem: "MINGW32"
|
||||
install: mingw-w64-i686-cmake mingw-w64-i686-ninja mingw-w64-i686-gcc
|
||||
type: Debug
|
||||
env:
|
||||
CMAKE_GENERATOR: Ninja
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
msystem: ${{ matrix.msystem }}
|
||||
install: ${{ matrix.install }}
|
||||
- name: Build and Test
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DFASTFLOAT_TEST=ON ..
|
||||
cmake --build . --verbose
|
||||
ctest --output-on-failure -R basictest
|
||||
25
.github/workflows/vs16-clang-ci.yml
vendored
Normal file
25
.github/workflows/vs16-clang-ci.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
ame: VS16-CLANG-CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: windows-vs16
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: 'Run CMake with VS16'
|
||||
uses: lukka/run-cmake@v2
|
||||
with:
|
||||
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
|
||||
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
|
||||
buildDirectory: "${{ github.workspace }}/../../_temp/windows"
|
||||
cmakeBuildType: Release
|
||||
buildWithCMake: true
|
||||
cmakeGenerator: VS16Win64
|
||||
cmakeAppendedArgs: -T ClangCL -DFASTFLOAT_TEST=ON
|
||||
buildWithCMakeArgs: --config Release
|
||||
|
||||
- name: 'Run CTest'
|
||||
run: ctest -C Release -R basictest --output-on-failure
|
||||
working-directory: "${{ github.workspace }}/../../_temp/windows"
|
||||
@ -18,14 +18,17 @@
|
||||
#define fastfloat_really_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define fastfloat_strcasecmp _stricmp
|
||||
#define fastfloat_strncasecmp _strnicmp
|
||||
#else
|
||||
#define fastfloat_strcasecmp strcasecmp
|
||||
#define fastfloat_strncasecmp strncasecmp
|
||||
#endif
|
||||
namespace fast_float {
|
||||
|
||||
// Compares two ASCII strings in a case insensitive manner.
|
||||
inline bool fastfloat_strncasecmp(const char * input1, const char * input2, size_t length) {
|
||||
char running_diff{0};
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
running_diff |= (input1[i] ^ input2[i]);
|
||||
}
|
||||
return (running_diff == 0) || (running_diff == 32);
|
||||
}
|
||||
|
||||
#ifndef FLT_EVAL_METHOD
|
||||
#error "FLT_EVAL_METHOD should be defined, please include cfloat."
|
||||
#endif
|
||||
@ -72,7 +75,8 @@ int leading_zeroes(uint64_t input_num) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#if defined(_WIN32) && !defined(__clang__)
|
||||
// Note MinGW falls here too
|
||||
#include <intrin.h>
|
||||
|
||||
#if !defined(_M_X64) && !defined(_M_ARM64)// _umul128 for x86, arm
|
||||
|
||||
@ -4,6 +4,25 @@
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
// Anything at all that is related to cygwin, msys and so forth will
|
||||
// always use this fallback because we cannot rely on it behaving as normal
|
||||
// gcc.
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
// workaround for CYGWIN
|
||||
double cygwin_strtod_l(const char* start, char** end) {
|
||||
double d;
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss << start;
|
||||
ss >> d;
|
||||
size_t nread = ss.tellg();
|
||||
*end = const_cast<char*>(start) + nread;
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T> char *to_string(T d, char *buffer) {
|
||||
auto written = std::snprintf(buffer, 64, "%.*e",
|
||||
std::numeric_limits<T>::max_digits10 - 1, d);
|
||||
@ -12,7 +31,9 @@ template <typename T> char *to_string(T d, char *buffer) {
|
||||
|
||||
void strtod_from_string(const char * st, float& d) {
|
||||
char *pr = (char *)st;
|
||||
#ifdef _WIN32
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
d = cygwin_strtod_l(st, &pr);
|
||||
#elif defined(_WIN32)
|
||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||
d = _strtof_l(st, &pr, c_locale);
|
||||
#else
|
||||
@ -73,6 +94,9 @@ void allvalues() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
|
||||
#endif
|
||||
allvalues();
|
||||
std::cout << std::endl;
|
||||
std::cout << "all ok" << std::endl;
|
||||
|
||||
@ -2,6 +2,25 @@
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
// Anything at all that is related to cygwin, msys and so forth will
|
||||
// always use this fallback because we cannot rely on it behaving as normal
|
||||
// gcc.
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
// workaround for CYGWIN
|
||||
double cygwin_strtod_l(const char* start, char** end) {
|
||||
double d;
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss << start;
|
||||
ss >> d;
|
||||
size_t nread = ss.tellg();
|
||||
*end = const_cast<char*>(start) + nread;
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
class RandomEngine {
|
||||
public:
|
||||
RandomEngine() = delete;
|
||||
@ -103,7 +122,9 @@ std::pair<double, bool> strtod_from_string(char *st) {
|
||||
std::pair<float, bool> strtof_from_string(char *st) {
|
||||
float d;
|
||||
char *pr;
|
||||
#ifdef _WIN32
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
d = cygwin_strtod_l(st, &pr);
|
||||
#elif defined(_WIN32)
|
||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||
d = _strtof_l(st, &pr, c_locale);
|
||||
#else
|
||||
@ -178,6 +199,9 @@ bool tester(int seed, size_t volume) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
|
||||
#endif
|
||||
if (tester(1234344, 100000000)) {
|
||||
std::cout << "All tests ok." << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@ -2,6 +2,25 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
// Anything at all that is related to cygwin, msys and so forth will
|
||||
// always use this fallback because we cannot rely on it behaving as normal
|
||||
// gcc.
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
// workaround for CYGWIN
|
||||
double cygwin_strtod_l(const char* start, char** end) {
|
||||
double d;
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss << start;
|
||||
ss >> d;
|
||||
size_t nread = ss.tellg();
|
||||
*end = const_cast<char*>(start) + nread;
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void Assert(bool Assertion) {
|
||||
if (!Assertion)
|
||||
throw std::runtime_error("bug");
|
||||
@ -50,30 +69,32 @@ void strtod_from_string(const std::string &st, T& d);
|
||||
|
||||
template <>
|
||||
void strtod_from_string(const std::string &st, double& d) {
|
||||
char *pr = (char *)st.data();
|
||||
char *pr = (char *)st.c_str();
|
||||
#ifdef _WIN32
|
||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||
d = _strtod_l(st.data(), &pr, c_locale);
|
||||
d = _strtod_l(st.c_str(), &pr, c_locale);
|
||||
#else
|
||||
static locale_t c_locale = newlocale(LC_ALL_MASK, "C", NULL);
|
||||
d = strtod_l(st.data(), &pr, c_locale);
|
||||
d = strtod_l(st.c_str(), &pr, c_locale);
|
||||
#endif
|
||||
if (pr == st.data()) {
|
||||
if (pr == st.c_str()) {
|
||||
throw std::runtime_error("bug in strtod_from_string");
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void strtod_from_string(const std::string &st, float& d) {
|
||||
char *pr = (char *)st.data();
|
||||
#ifdef _WIN32
|
||||
char *pr = (char *)st.c_str();
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
d = cygwin_strtod_l(st.c_str(), &pr);
|
||||
#elif defined(_WIN32)
|
||||
static _locale_t c_locale = _create_locale(LC_ALL, "C");
|
||||
d = _strtof_l(st.data(), &pr, c_locale);
|
||||
d = _strtof_l(st.c_str(), &pr, c_locale);
|
||||
#else
|
||||
static locale_t c_locale = newlocale(LC_ALL_MASK, "C", NULL);
|
||||
d = strtof_l(st.data(), &pr, c_locale);
|
||||
d = strtof_l(st.c_str(), &pr, c_locale);
|
||||
#endif
|
||||
if (pr == st.data()) {
|
||||
if (pr == st.c_str()) {
|
||||
throw std::runtime_error("bug in strtod_from_string");
|
||||
}
|
||||
}
|
||||
@ -215,7 +236,9 @@ bool partow_test() {
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
std::cout << "Warning: msys/cygwin detected. This particular test is likely to generate false failures due to our reliance on the underlying runtime library." << std::endl;
|
||||
#endif
|
||||
std::cout << "32 bits checks" << std::endl;
|
||||
Assert(partow_test<float>());
|
||||
Assert(test<float>());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user