Merge pull request #2453 from kuzkry:gtest-port-clean-up_kMaxBiggestInt

PiperOrigin-RevId: 278008286
This commit is contained in:
Xiaoyi Zhang 2019-11-04 11:43:27 -05:00
commit 8697709e03
6 changed files with 89 additions and 70 deletions

View File

@ -133,7 +133,7 @@ GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
// nor PrintTo(). // nor PrintTo().
enum TypeKind { enum TypeKind {
kProtobuf, // a protobuf type kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to std::intmax_t kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type) // (e.g. a named or unnamed enum type)
#if GTEST_HAS_ABSL #if GTEST_HAS_ABSL
kConvertibleToStringView, // a type implicitly convertible to kConvertibleToStringView, // a type implicitly convertible to
@ -179,14 +179,14 @@ template <typename T>
class TypeWithoutFormatter<T, kConvertibleToInteger> { class TypeWithoutFormatter<T, kConvertibleToInteger> {
public: public:
// Since T has no << operator or PrintTo() but can be implicitly // Since T has no << operator or PrintTo() but can be implicitly
// converted to the maximum width integer, we print it as a std::intmax_t. // converted to BiggestInt, we print it as a BiggestInt.
// //
// Most likely T is an enum type (either named or unnamed), in which // Most likely T is an enum type (either named or unnamed), in which
// case printing it as an integer is the desired behavior. In case // case printing it as an integer is the desired behavior. In case
// T is not an enum, printing it as an integer is the best we can do // T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer. // given that it has no user-defined printer.
static void PrintValue(const T& value, ::std::ostream* os) { static void PrintValue(const T& value, ::std::ostream* os) {
const std::intmax_t kBigInt = value; const internal::BiggestInt kBigInt = value;
*os << kBigInt; *os << kBigInt;
} }
}; };
@ -206,7 +206,7 @@ class TypeWithoutFormatter<T, kConvertibleToStringView> {
// Prints the given value to the given ostream. If the value is a // Prints the given value to the given ostream. If the value is a
// protocol message, its debug string is printed; if it's an enum or // protocol message, its debug string is printed; if it's an enum or
// of a type implicitly convertible to std::intmax_t, it's printed as an // of a type implicitly convertible to BiggestInt, it's printed as an
// integer; otherwise the bytes in the value are printed. This is // integer; otherwise the bytes in the value are printed. This is
// what UniversalPrinter<T>::Print() does when it knows nothing about // what UniversalPrinter<T>::Print() does when it knows nothing about
// type T and T has neither << operator nor PrintTo(). // type T and T has neither << operator nor PrintTo().
@ -231,14 +231,15 @@ class TypeWithoutFormatter<T, kConvertibleToStringView> {
template <typename Char, typename CharTraits, typename T> template <typename Char, typename CharTraits, typename T>
::std::basic_ostream<Char, CharTraits>& operator<<( ::std::basic_ostream<Char, CharTraits>& operator<<(
::std::basic_ostream<Char, CharTraits>& os, const T& x) { ::std::basic_ostream<Char, CharTraits>& os, const T& x) {
TypeWithoutFormatter< TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
T, (internal::IsAProtocolMessage<T>::value
? kProtobuf ? kProtobuf
: std::is_convertible<const T&, std::intmax_t>::value : std::is_convertible<
const T&, internal::BiggestInt>::value
? kConvertibleToInteger ? kConvertibleToInteger
: :
#if GTEST_HAS_ABSL #if GTEST_HAS_ABSL
std::is_convertible<const T&, absl::string_view>::value std::is_convertible<
const T&, absl::string_view>::value
? kConvertibleToStringView ? kConvertibleToStringView
: :
#endif #endif

View File

@ -1531,11 +1531,13 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs); return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
} }
// With this overloaded version, we allow anonymous enums to be used in // With this overloaded version, we allow anonymous enums to be used
// {ASSERT|EXPECT}_EQ as anonymous enums can be implicitly cast to integers. // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums
// can be implicitly cast to BiggestInt.
GTEST_API_ AssertionResult CmpHelperEQ(const char* lhs_expression, GTEST_API_ AssertionResult CmpHelperEQ(const char* lhs_expression,
const char* rhs_expression, const char* rhs_expression,
std::intmax_t lhs, std::intmax_t rhs); BiggestInt lhs,
BiggestInt rhs);
class EqHelper { class EqHelper {
public: public:
@ -1552,14 +1554,16 @@ class EqHelper {
return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
} }
// With this overloaded version, we allow anonymous enums to be used in // With this overloaded version, we allow anonymous enums to be used
// {ASSERT|EXPECT}_EQ as anonymous enums can be implicitly cast to integers. // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous
// enums can be implicitly cast to BiggestInt.
// //
// Even though its body looks the same as the above version, we // Even though its body looks the same as the above version, we
// cannot merge the two, as it will make anonymous enums unhappy. // cannot merge the two, as it will make anonymous enums unhappy.
static AssertionResult Compare(const char* lhs_expression, static AssertionResult Compare(const char* lhs_expression,
const char* rhs_expression, std::intmax_t lhs, const char* rhs_expression,
std::intmax_t rhs) { BiggestInt lhs,
BiggestInt rhs) {
return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
} }
@ -1592,8 +1596,9 @@ AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,
// of similar code. // of similar code.
// //
// For each templatized helper function, we also define an overloaded // For each templatized helper function, we also define an overloaded
// version for std::intmax_t in order to reduce code bloat and allow // version for BiggestInt in order to reduce code bloat and allow
// anonymous enums to be used with {ASSERT|EXPECT}_??. // anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled
// with gcc 4.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
@ -1608,8 +1613,7 @@ AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2,
}\ }\
}\ }\
GTEST_API_ AssertionResult CmpHelper##op_name(\ GTEST_API_ AssertionResult CmpHelper##op_name(\
const char* expr1, const char* expr2, std::intmax_t val1, \ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2)
std::intmax_t val2)
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.

View File

@ -225,6 +225,7 @@
// TypeWithSize - maps an integer to a int type. // TypeWithSize - maps an integer to a int type.
// Int32, UInt32, Int64, UInt64, TimeInMillis // Int32, UInt32, Int64, UInt64, TimeInMillis
// - integers of known sizes. // - integers of known sizes.
// BiggestInt - the biggest signed integer type.
// //
// Command-line utilities: // Command-line utilities:
// GTEST_DECLARE_*() - declares a flag. // GTEST_DECLARE_*() - declares a flag.
@ -1875,9 +1876,12 @@ GTEST_API_ size_t GetThreadCount();
#if GTEST_OS_WINDOWS #if GTEST_OS_WINDOWS
# define GTEST_PATH_SEP_ "\\" # define GTEST_PATH_SEP_ "\\"
# define GTEST_HAS_ALT_PATH_SEP_ 1 # define GTEST_HAS_ALT_PATH_SEP_ 1
// The biggest signed integer type the compiler supports.
typedef __int64 BiggestInt;
#else #else
# define GTEST_PATH_SEP_ "/" # define GTEST_PATH_SEP_ "/"
# define GTEST_HAS_ALT_PATH_SEP_ 0 # define GTEST_HAS_ALT_PATH_SEP_ 0
typedef long long BiggestInt; // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
// Utilities for char. // Utilities for char.
@ -2080,6 +2084,16 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_()
# define GTEST_SNPRINTF_ snprintf # define GTEST_SNPRINTF_ snprintf
#endif #endif
// The maximum number a BiggestInt can represent. This definition
// works no matter BiggestInt is represented in one's complement or
// two's complement.
//
// We cannot rely on numeric_limits in STL, as __int64 and long long
// are not part of standard C++ and numeric_limits doesn't need to be
// defined for them.
const BiggestInt kMaxBiggestInt =
~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1));
// This template class serves as a compile-time function from size to // This template class serves as a compile-time function from size to
// type. It maps a size in bytes to a primitive type with that // type. It maps a size in bytes to a primitive type with that
// size. e.g. // size. e.g.

View File

@ -1442,8 +1442,9 @@ namespace internal {
// The helper function for {ASSERT|EXPECT}_EQ with int or enum // The helper function for {ASSERT|EXPECT}_EQ with int or enum
// arguments. // arguments.
AssertionResult CmpHelperEQ(const char* lhs_expression, AssertionResult CmpHelperEQ(const char* lhs_expression,
const char* rhs_expression, std::intmax_t lhs, const char* rhs_expression,
std::intmax_t rhs) { BiggestInt lhs,
BiggestInt rhs) {
if (lhs == rhs) { if (lhs == rhs) {
return AssertionSuccess(); return AssertionSuccess();
} }
@ -1460,7 +1461,7 @@ AssertionResult CmpHelperEQ(const char* lhs_expression,
// just to avoid copy-and-paste of similar code. // just to avoid copy-and-paste of similar code.
#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ #define GTEST_IMPL_CMP_HELPER_(op_name, op)\
AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \
std::intmax_t val1, std::intmax_t val2) { \ BiggestInt val1, BiggestInt val2) {\
if (val1 op val2) {\ if (val1 op val2) {\
return AssertionSuccess();\ return AssertionSuccess();\
} else {\ } else {\

View File

@ -83,12 +83,10 @@ void PrintTo(EnumWithPrintTo e, std::ostream* os) {
*os << (e == kEWPT1 ? "kEWPT1" : "invalid"); *os << (e == kEWPT1 ? "kEWPT1" : "invalid");
} }
// A class implicitly convertible to std::intmax_t. // A class implicitly convertible to BiggestInt.
class IntMaxConvertible { class BiggestIntConvertible {
public: public:
constexpr operator std::intmax_t() const { // NOLINT(runtime/explicit) operator ::testing::internal::BiggestInt() const { return 42; }
return 42;
}
}; };
// A user-defined unprintable class template in the global namespace. // A user-defined unprintable class template in the global namespace.
@ -269,10 +267,10 @@ TEST(PrintEnumTest, EnumWithPrintTo) {
EXPECT_EQ("invalid", Print(static_cast<EnumWithPrintTo>(0))); EXPECT_EQ("invalid", Print(static_cast<EnumWithPrintTo>(0)));
} }
// Tests printing a class implicitly convertible to std::intmax_t. // Tests printing a class implicitly convertible to BiggestInt.
TEST(PrintClassTest, IntMaxConvertible) { TEST(PrintClassTest, BiggestIntConvertible) {
EXPECT_EQ("42", Print(IntMaxConvertible())); EXPECT_EQ("42", Print(BiggestIntConvertible()));
} }
// Tests printing various char types. // Tests printing various char types.
@ -527,8 +525,9 @@ TEST(PrintPointerTest, NonMemberFunctionPointer) {
// standard disallows casting between pointers to functions and // standard disallows casting between pointers to functions and
// pointers to objects, and some compilers (e.g. GCC 3.4) enforce // pointers to objects, and some compilers (e.g. GCC 3.4) enforce
// this limitation. // this limitation.
EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>( EXPECT_EQ(
reinterpret_cast<std::intptr_t>(&MyFunction))), PrintPointer(reinterpret_cast<const void*>(
reinterpret_cast<internal::BiggestInt>(&MyFunction))),
Print(&MyFunction)); Print(&MyFunction));
int (*p)(bool) = NULL; // NOLINT int (*p)(bool) = NULL; // NOLINT
EXPECT_EQ("NULL", Print(p)); EXPECT_EQ("NULL", Print(p));
@ -1121,8 +1120,8 @@ TEST(PrintReferenceTest, HandlesFunctionPointer) {
// standard disallows casting between pointers to functions and // standard disallows casting between pointers to functions and
// pointers to objects, and some compilers (e.g. GCC 3.4) enforce // pointers to objects, and some compilers (e.g. GCC 3.4) enforce
// this limitation. // this limitation.
const std::string fp_string = PrintPointer( const std::string fp_string = PrintPointer(reinterpret_cast<const void*>(
reinterpret_cast<const void*>(reinterpret_cast<std::intptr_t>(fp))); reinterpret_cast<internal::BiggestInt>(fp)));
EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, EXPECT_EQ("@" + fp_pointer_string + " " + fp_string,
PrintByRef(fp)); PrintByRef(fp));
} }

View File

@ -55,11 +55,11 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused.
} }
#include <limits.h> // For INT_MAX.
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <limits>
#include <map> #include <map>
#include <ostream> #include <ostream>
#include <type_traits> #include <type_traits>
@ -3952,11 +3952,11 @@ enum {
// On Linux, kCaseB and kCaseA have the same value when truncated to // On Linux, kCaseB and kCaseA have the same value when truncated to
// int size. We want to test whether this will confuse the // int size. We want to test whether this will confuse the
// assertions. // assertions.
kCaseB = (std::numeric_limits<std::intmax_t>::max)(), kCaseB = testing::internal::kMaxBiggestInt,
# else # else
kCaseB = (std::numeric_limits<int>::max)(), kCaseB = INT_MAX,
# endif // GTEST_OS_LINUX # endif // GTEST_OS_LINUX