Guard against min/max being macros in reader.h
Sometimes, particularly when Microsoft's windows.h is included, min/max are defined as macros, interfering with use of std::numeric_limits::min() and the like. To guard against this, the function name is wrapped in an extra set of parenthesis, which inhibits function-style macro expansion. This is a similar commit to 6e38649ec6, but fixes uses of std::numeric_limits added after that commit, like those introduced in 2ea43433e2.
This commit is contained in:
parent
129d19ba7f
commit
960b9cfd19
@ -606,7 +606,7 @@ public:
|
|||||||
parseResult_.Clear();
|
parseResult_.Clear();
|
||||||
state_ = IterativeParsingStartState;
|
state_ = IterativeParsingStartState;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Parse one token from JSON text
|
//! Parse one token from JSON text
|
||||||
/*! \tparam InputStream Type of input stream, implementing Stream concept
|
/*! \tparam InputStream Type of input stream, implementing Stream concept
|
||||||
\tparam Handler Type of handler, implementing Handler concept.
|
\tparam Handler Type of handler, implementing Handler concept.
|
||||||
@ -618,11 +618,11 @@ public:
|
|||||||
bool IterativeParseNext(InputStream& is, Handler& handler) {
|
bool IterativeParseNext(InputStream& is, Handler& handler) {
|
||||||
while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
|
while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
|
|
||||||
Token t = Tokenize(is.Peek());
|
Token t = Tokenize(is.Peek());
|
||||||
IterativeParsingState n = Predict(state_, t);
|
IterativeParsingState n = Predict(state_, t);
|
||||||
IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
|
IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
|
||||||
|
|
||||||
// If we've finished or hit an error...
|
// If we've finished or hit an error...
|
||||||
if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
|
if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
|
||||||
// Report errors.
|
// Report errors.
|
||||||
@ -630,11 +630,11 @@ public:
|
|||||||
HandleError(state_, is);
|
HandleError(state_, is);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition to the finish state.
|
// Transition to the finish state.
|
||||||
RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
|
RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
|
||||||
state_ = d;
|
state_ = d;
|
||||||
|
|
||||||
// If StopWhenDone is not set...
|
// If StopWhenDone is not set...
|
||||||
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
||||||
// ... and extra non-whitespace data is found...
|
// ... and extra non-whitespace data is found...
|
||||||
@ -645,11 +645,11 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success! We are done!
|
// Success! We are done!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition to the new state.
|
// Transition to the new state.
|
||||||
state_ = d;
|
state_ = d;
|
||||||
|
|
||||||
@ -657,7 +657,7 @@ public:
|
|||||||
if (!IsIterativeParsingDelimiterState(n))
|
if (!IsIterativeParsingDelimiterState(n))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We reached the end of file.
|
// We reached the end of file.
|
||||||
stack_.Clear();
|
stack_.Clear();
|
||||||
|
|
||||||
@ -665,10 +665,10 @@ public:
|
|||||||
HandleError(state_, is);
|
HandleError(state_, is);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Check if token-by-token parsing JSON text is complete
|
//! Check if token-by-token parsing JSON text is complete
|
||||||
/*! \return Whether the JSON has been fully decoded.
|
/*! \return Whether the JSON has been fully decoded.
|
||||||
*/
|
*/
|
||||||
@ -1523,7 +1523,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
|
if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
|
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
|
||||||
}
|
}
|
||||||
@ -1701,7 +1701,7 @@ private:
|
|||||||
d = internal::StrtodNormalPrecision(d, p);
|
d = internal::StrtodNormalPrecision(d, p);
|
||||||
|
|
||||||
// Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
|
// Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
|
||||||
if (d > std::numeric_limits<double>::max()) {
|
if (d > (std::numeric_limits<double>::max)()) {
|
||||||
// Overflow
|
// Overflow
|
||||||
// TODO: internal::StrtodX should report overflow (or underflow)
|
// TODO: internal::StrtodX should report overflow (or underflow)
|
||||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
|
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
|
||||||
@ -1769,12 +1769,12 @@ private:
|
|||||||
|
|
||||||
// Single value state
|
// Single value state
|
||||||
IterativeParsingValueState,
|
IterativeParsingValueState,
|
||||||
|
|
||||||
// Delimiter states (at bottom)
|
// Delimiter states (at bottom)
|
||||||
IterativeParsingElementDelimiterState,
|
IterativeParsingElementDelimiterState,
|
||||||
IterativeParsingMemberDelimiterState,
|
IterativeParsingMemberDelimiterState,
|
||||||
IterativeParsingKeyValueDelimiterState,
|
IterativeParsingKeyValueDelimiterState,
|
||||||
|
|
||||||
cIterativeParsingStateCount
|
cIterativeParsingStateCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2167,43 +2167,43 @@ private:
|
|||||||
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
|
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
|
||||||
return s >= IterativeParsingElementDelimiterState;
|
return s >= IterativeParsingElementDelimiterState;
|
||||||
}
|
}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
|
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
|
||||||
return s <= IterativeParsingErrorState;
|
return s <= IterativeParsingErrorState;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned parseFlags, typename InputStream, typename Handler>
|
template <unsigned parseFlags, typename InputStream, typename Handler>
|
||||||
ParseResult IterativeParse(InputStream& is, Handler& handler) {
|
ParseResult IterativeParse(InputStream& is, Handler& handler) {
|
||||||
parseResult_.Clear();
|
parseResult_.Clear();
|
||||||
ClearStackOnExit scope(*this);
|
ClearStackOnExit scope(*this);
|
||||||
IterativeParsingState state = IterativeParsingStartState;
|
IterativeParsingState state = IterativeParsingStartState;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
while (is.Peek() != '\0') {
|
while (is.Peek() != '\0') {
|
||||||
Token t = Tokenize(is.Peek());
|
Token t = Tokenize(is.Peek());
|
||||||
IterativeParsingState n = Predict(state, t);
|
IterativeParsingState n = Predict(state, t);
|
||||||
IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
|
IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
|
||||||
|
|
||||||
if (d == IterativeParsingErrorState) {
|
if (d == IterativeParsingErrorState) {
|
||||||
HandleError(state, is);
|
HandleError(state, is);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = d;
|
state = d;
|
||||||
|
|
||||||
// Do not further consume streams if a root JSON has been parsed.
|
// Do not further consume streams if a root JSON has been parsed.
|
||||||
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
|
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SkipWhitespaceAndComments<parseFlags>(is);
|
SkipWhitespaceAndComments<parseFlags>(is);
|
||||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the end of file.
|
// Handle the end of file.
|
||||||
if (state != IterativeParsingFinishState)
|
if (state != IterativeParsingFinishState)
|
||||||
HandleError(state, is);
|
HandleError(state, is);
|
||||||
|
|
||||||
return parseResult_;
|
return parseResult_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
@ -7,9 +7,9 @@
|
|||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#include "unittest.h"
|
#include "unittest.h"
|
||||||
@ -61,7 +61,7 @@ static void VerifyValue(T value, void(*f)(T, char*), char* (*g)(T, char*)) {
|
|||||||
|
|
||||||
f(value, buffer1);
|
f(value, buffer1);
|
||||||
*g(value, buffer2) = '\0';
|
*g(value, buffer2) = '\0';
|
||||||
|
|
||||||
|
|
||||||
EXPECT_STREQ(buffer1, buffer2);
|
EXPECT_STREQ(buffer1, buffer2);
|
||||||
}
|
}
|
||||||
@ -79,12 +79,12 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) {
|
|||||||
do {
|
do {
|
||||||
VerifyValue<T>(i - 1, f, g);
|
VerifyValue<T>(i - 1, f, g);
|
||||||
VerifyValue<T>(i, f, g);
|
VerifyValue<T>(i, f, g);
|
||||||
if (std::numeric_limits<T>::min() < 0) {
|
if ((std::numeric_limits<T>::min)() < 0) {
|
||||||
VerifyValue<T>(Traits<T>::Negate(i), f, g);
|
VerifyValue<T>(Traits<T>::Negate(i), f, g);
|
||||||
VerifyValue<T>(Traits<T>::Negate(i + 1), f, g);
|
VerifyValue<T>(Traits<T>::Negate(i + 1), f, g);
|
||||||
}
|
}
|
||||||
last = i;
|
last = i;
|
||||||
if (i > static_cast<T>(std::numeric_limits<T>::max() / static_cast<T>(power)))
|
if (i > static_cast<T>((std::numeric_limits<T>::max)() / static_cast<T>(power)))
|
||||||
break;
|
break;
|
||||||
i *= static_cast<T>(power);
|
i *= static_cast<T>(power);
|
||||||
} while (last < i);
|
} while (last < i);
|
||||||
|
@ -422,7 +422,7 @@ static void TestParseDouble() {
|
|||||||
"67546703537516986049910576551282076245490090389328944075868508455133942"
|
"67546703537516986049910576551282076245490090389328944075868508455133942"
|
||||||
"30458323690322294816580855933212334827479782620414472316873817718091929"
|
"30458323690322294816580855933212334827479782620414472316873817718091929"
|
||||||
"9881250404026184124858368",
|
"9881250404026184124858368",
|
||||||
std::numeric_limits<double>::max());
|
(std::numeric_limits<double>::max)());
|
||||||
|
|
||||||
TEST_DOUBLE(fullPrecision,
|
TEST_DOUBLE(fullPrecision,
|
||||||
"243546080556034731077856379609316893158278902575447060151047"
|
"243546080556034731077856379609316893158278902575447060151047"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user