From 6e38649ec61e5f4f382c257a6b27698bb55eff61 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Tue, 5 Sep 2017 18:23:28 -0700 Subject: [PATCH 1/2] Guard against min/max being macros in document.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. --- include/rapidjson/document.h | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 3133a2f9..191582e9 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -29,14 +29,6 @@ RAPIDJSON_DIAG_PUSH #ifdef _MSC_VER RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data -#ifdef _MINWINDEF_ // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max -#ifndef NOMINMAX -#pragma push_macro("min") -#pragma push_macro("max") -#undef min -#undef max -#endif -#endif #endif #ifdef __clang__ @@ -1018,14 +1010,14 @@ public: uint64_t u = GetUint64(); volatile double d = static_cast(u); return (d >= 0.0) - && (d < static_cast(std::numeric_limits::max())) + && (d < static_cast((std::numeric_limits::max)())) && (u == static_cast(d)); } if (IsInt64()) { int64_t i = GetInt64(); volatile double d = static_cast(i); - return (d >= static_cast(std::numeric_limits::min())) - && (d < static_cast(std::numeric_limits::max())) + return (d >= static_cast((std::numeric_limits::min)())) + && (d < static_cast((std::numeric_limits::max)())) && (i == static_cast(d)); } return true; // double, int, uint are always lossless @@ -1042,8 +1034,8 @@ public: bool IsLosslessFloat() const { if (!IsNumber()) return false; double a = GetDouble(); - if (a < static_cast(-std::numeric_limits::max()) - || a > static_cast(std::numeric_limits::max())) + if (a < static_cast(-(std::numeric_limits::max)()) + || a > static_cast((std::numeric_limits::max)())) return false; double b = static_cast(static_cast(a)); return a >= b && a <= b; // Prevent -Wfloat-equal @@ -2616,12 +2608,6 @@ private: }; RAPIDJSON_NAMESPACE_END -#ifdef _MINWINDEF_ // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max -#ifndef NOMINMAX -#pragma pop_macro("min") -#pragma pop_macro("max") -#endif -#endif RAPIDJSON_DIAG_POP #endif // RAPIDJSON_DOCUMENT_H_ From e4c0ecf86b7db94014cde331cd43b6443f993be7 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Tue, 5 Sep 2017 18:27:02 -0700 Subject: [PATCH 2/2] Guard against min/max macros in tests too --- test/unittest/itoatest.cpp | 4 ++-- test/unittest/readertest.cpp | 2 +- test/unittest/strtodtest.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unittest/itoatest.cpp b/test/unittest/itoatest.cpp index 2f66bedc..f41edeb7 100644 --- a/test/unittest/itoatest.cpp +++ b/test/unittest/itoatest.cpp @@ -70,8 +70,8 @@ template static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) { // Boundary cases VerifyValue(0, f, g); - VerifyValue(std::numeric_limits::min(), f, g); - VerifyValue(std::numeric_limits::max(), f, g); + VerifyValue((std::numeric_limits::min)(), f, g); + VerifyValue((std::numeric_limits::max)(), f, g); // 2^n - 1, 2^n, 10^n - 1, 10^n until overflow for (int power = 2; power <= 10; power += 8) { diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 5078f524..dad33d69 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -415,7 +415,7 @@ TEST(Reader, ParseNumber_NormalPrecisionError) { uint64_t bias1 = e.ToBias(); uint64_t bias2 = a.ToBias(); double ulp = static_cast(bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1); - ulpMax = std::max(ulpMax, ulp); + ulpMax = (std::max)(ulpMax, ulp); ulpSum += ulp; } printf("ULP Average = %g, Max = %g \n", ulpSum / count, ulpMax); diff --git a/test/unittest/strtodtest.cpp b/test/unittest/strtodtest.cpp index cde836c7..807f8872 100644 --- a/test/unittest/strtodtest.cpp +++ b/test/unittest/strtodtest.cpp @@ -91,7 +91,7 @@ TEST(Strtod, CheckApproximationCase) { } // Remove common power of two factor from all three scaled values - int common_Exp2 = std::min(dS_Exp2, std::min(bS_Exp2, hS_Exp2)); + int common_Exp2 = (std::min)(dS_Exp2, (std::min)(bS_Exp2, hS_Exp2)); dS_Exp2 -= common_Exp2; bS_Exp2 -= common_Exp2; hS_Exp2 -= common_Exp2;