replace strtold with non locale dependent version#337
replace strtold with non locale dependent version#337whackashoe wants to merge 14 commits intonlohmann:developfrom
Conversation
|
Thanks for the PR! I'll check it as soon as I find the time. |
|
Just one question: Can the code be licensed under the MIT license? |
|
Yeah I think it's fine, it's basically all rewritten so I don't think there is much of an issue that way... plus if they attempted to sue for using a similar variable name or if statement we'd probably become famous. If you want to be extra safe we can change the comments to be unique as they are just copied verbatim, though I think that'd be horrid as their comments are quite nice. |
src/json.hpp
Outdated
| standard floating point number parsing function based on the type | ||
| supplied via the first parameter. Set this to @a | ||
| static_cast<number_float_t*>(nullptr). | ||
| while (nl_isspace(*fst)) |
There was a problem hiding this comment.
Whitespace is already skipped by the lexer, so I think it is safe to skip this loop.
src/json.hpp
Outdated
| if (cp == '-' or cp == '+') | ||
| { | ||
| ++fst; | ||
| successful_parse = true; |
There was a problem hiding this comment.
The lexer discards any string that violates JSON's specification for numbers. Therefore, we do not need additional verification here.
|
Since it is relying on other conditions now with these 2 changes, I think we can strip out endptr and errno as well. |
this changes a few things. the name of the function to better represent what it does (string to json number) - we aren't strtoul compliant so best not to lie about that. we remove template code and just use one function. this makes it a bit simpler and we can always add it back if it buys us anything. the penalty for casting down from long double seems to be inconsequential.
|
The
|
src/json.hpp.re2c
Outdated
| if (*str == 'e' or *str == 'E') | ||
| { | ||
| cp = *++str; | ||
| bool negative_exp = cp == '-'; // read in exponent sign (+/-) |
There was a problem hiding this comment.
negative_exp could be const bool
| while (nl_isdigit(cp = *str)) | ||
| { | ||
| result = result * 10 + (cp - '0'); | ||
| ++str; |
There was a problem hiding this comment.
Couldn't str be incremented in the while condition just like in the loop below?
There was a problem hiding this comment.
No, we may not want to increment if nl_isdigit fails so it must be in body.
src/json.hpp.re2c
Outdated
| supplied via the first parameter. Set this to @a | ||
| static_cast<number_float_t*>(nullptr). | ||
| int count = 0; // exponent calculation | ||
| if (! nl_isdigit(cp)) |
| {1.e1L, 1.e2L, 1.e4L, 1.e8L, 1.e16L, 1.e32L, 1.e64L, 1.e128L, 1.e256L} | ||
| }; | ||
|
|
||
| if (exp > std::numeric_limits<long double>::max_exponent10) |
There was a problem hiding this comment.
Starting here, there a now comments in the code. Please briefly describe each conditional and loop.
|
@nlohmann could you add help-wanted tag to this, I am too busy right now to do anything with this right now but it is very close. |
|
Hey @whackashoe do you need help with this? |
|
@nlohmann Yes. I haven't had time to figure out the last issues with this, though iirc its basically at a level where it works except for an edge case (maybe more than one). |
|
I'll have a look. I may open a feature branch myself for the moment to fix the conflicts and fiddle around a bit. |
|
I opened a feature branch. I changed the parser to reject incomplete numbers. This helped to simplify the number parser. There are still three tests failing - I'll check tomorrow. |
| { | ||
| if (plus_or_minus) | ||
| { | ||
| *--str; |
There was a problem hiding this comment.
Why is there a '*' here?
There was a problem hiding this comment.
Thanks for taking a look! @nlohmann want to incorp these into your feature branch?
There was a problem hiding this comment.
This makes no sense. Please have a look at https://github.com/nlohmann/json/blob/feature/strtold/src/json.hpp.re2c#L8139 where I started an overworked version of this PR.
| } | ||
|
|
||
| @param[in] type the @ref number_float_t in use | ||
| *--str; |
|
Please have a look at https://github.com/nlohmann/json/blob/feature/strtold/src/json.hpp.re2c#L8139 where I started an overworked version of this PR, and also the discussion in #302. |
|
I see the code parses to long double, and then the return value is cast to float_number_t. |
|
Apparently implementing strtod correctly is harder than it seems. |
|
@whackashoe Any idea how to proceed here? I agree with @TurpentineDistillery that correct floating-point handling is really hard... |
|
What about this PR? Is it likely that the remaining issues can be fixed? There is also PR #378 dealing with the same issue. |
|
It seems like it will need significant changes to work. You can close this if it's dirtying up the queue, I don't have time to work on it for a while. |
|
Thanks for checking back. I close this for now. |
Move definition of common macros (e.g., JSON_HAS_CPP_*) into macros.hpp header file and update unit test sources. Incidentally enables the regression tests for nlohmann#2546 and nlohmann#3070. A CHECK_THROWS_WITH_AS in nlohmann#3070 was disabled, which is tracked here: nlohmann#337
Move definition of common macros (e.g., JSON_HAS_CPP_*) into macros.hpp header file and update unit test sources. Incidentally enables the regression tests for nlohmann#2546 and nlohmann#3070. A CHECK_THROWS_WITH_AS in nlohmann#3070 was disabled, which is tracked here: nlohmann#337
Move definition of common macros (e.g., JSON_HAS_CPP_*) into macros.hpp header file and update unit test sources. Incidentally enables the regression tests for nlohmann#2546 and nlohmann#3070. A CHECK_THROWS_WITH_AS in nlohmann#3070 was disabled, which is tracked here: nlohmann#337
Hi!
I've taken and reworked a strtod implementation from TI in order to provide this. It's rewritten in an attempt to be solid C++11 rather than C.
Using this fixes #302. It does not support octal or hexadecimal which JSON doesn't recognize in its number type anyway. This seems to be a bit more efficient (possibly due to non support of octal/hexadecimal) though I wouldn't be surprised if these gains disappear once the last few bugs are fixed heh.
Not all tests are passing yet but it's pretty close, perhaps someone can figure out the ones I haven't.
BEFORE:
AFTER:
UNIT TESTS:
(these are run with
CXX=clang++ make check)