Unverified Commit edadfecd authored by Akash Patel's avatar Akash Patel Committed by GitHub
Browse files

Update gtest to 1.11.0 (#1086)

Properly resolves #1083, #996.
parent 26e3b704
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
// Google C++ Testing and Mocking Framework definitions useful in production code. // Google C++ Testing and Mocking Framework definitions useful in production code.
// GOOGLETEST_CM0003 DO NOT DELETE // GOOGLETEST_CM0003 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
// When you need to test the private or protected members of a class, // When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the // use the FRIEND_TEST macro to declare your tests as friends of the
...@@ -58,4 +58,4 @@ ...@@ -58,4 +58,4 @@
#define FRIEND_TEST(test_case_name, test_name)\ #define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
// death tests. They are subject to change without notice. // death tests. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include "gtest/gtest-matchers.h" #include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
...@@ -301,4 +301,4 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); ...@@ -301,4 +301,4 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
...@@ -195,7 +195,7 @@ class GTEST_API_ FilePath { ...@@ -195,7 +195,7 @@ class GTEST_API_ FilePath {
void Normalize(); void Normalize();
// Returns a pointer to the last occurence of a valid path separator in // Returns a pointer to the last occurrence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path // the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found. // separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const; const char* FindLastPathSeparator() const;
...@@ -208,4 +208,4 @@ class GTEST_API_ FilePath { ...@@ -208,4 +208,4 @@ class GTEST_API_ FilePath {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <ctype.h> #include <ctype.h>
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
#include <cstdint>
#include <iomanip> #include <iomanip>
#include <limits> #include <limits>
#include <map> #include <map>
...@@ -78,9 +79,20 @@ ...@@ -78,9 +79,20 @@
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
// Stringifies its argument. // Stringifies its argument.
#define GTEST_STRINGIFY_(name) #name // Work around a bug in visual studio which doesn't accept code like this:
//
// #define GTEST_STRINGIFY_(name) #name
// #define MACRO(a, b, c) ... GTEST_STRINGIFY_(a) ...
// MACRO(, x, y)
//
// Complaining about the argument to GTEST_STRINGIFY_ being empty.
// This is allowed by the spec.
#define GTEST_STRINGIFY_HELPER_(name, ...) #name
#define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
namespace proto2 { class Message; } namespace proto2 {
class MessageLite;
}
namespace testing { namespace testing {
...@@ -275,7 +287,7 @@ class FloatingPoint { ...@@ -275,7 +287,7 @@ class FloatingPoint {
// //
// See the following article for more details on ULP: // See the following article for more details on ULP:
// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
static const size_t kMaxUlps = 4; static const uint32_t kMaxUlps = 4;
// Constructs a FloatingPoint from a raw floating-point number. // Constructs a FloatingPoint from a raw floating-point number.
// //
...@@ -508,6 +520,7 @@ struct SuiteApiResolver : T { ...@@ -508,6 +520,7 @@ struct SuiteApiResolver : T {
static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename, static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
int line_num) { int line_num) {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
SetUpTearDownSuiteFuncType test_case_fp = SetUpTearDownSuiteFuncType test_case_fp =
GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase); GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
SetUpTearDownSuiteFuncType test_suite_fp = SetUpTearDownSuiteFuncType test_suite_fp =
...@@ -519,10 +532,16 @@ struct SuiteApiResolver : T { ...@@ -519,10 +532,16 @@ struct SuiteApiResolver : T {
<< filename << ":" << line_num; << filename << ":" << line_num;
return test_case_fp != nullptr ? test_case_fp : test_suite_fp; return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
#else
(void)(filename);
(void)(line_num);
return &T::SetUpTestSuite;
#endif
} }
static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename, static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
int line_num) { int line_num) {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
SetUpTearDownSuiteFuncType test_case_fp = SetUpTearDownSuiteFuncType test_case_fp =
GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase); GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
SetUpTearDownSuiteFuncType test_suite_fp = SetUpTearDownSuiteFuncType test_suite_fp =
...@@ -534,6 +553,11 @@ struct SuiteApiResolver : T { ...@@ -534,6 +553,11 @@ struct SuiteApiResolver : T {
<< filename << ":" << line_num; << filename << ":" << line_num;
return test_case_fp != nullptr ? test_case_fp : test_suite_fp; return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
#else
(void)(filename);
(void)(line_num);
return &T::TearDownTestSuite;
#endif
} }
}; };
...@@ -542,11 +566,11 @@ struct SuiteApiResolver : T { ...@@ -542,11 +566,11 @@ struct SuiteApiResolver : T {
// //
// Arguments: // Arguments:
// //
// test_suite_name: name of the test suite // test_suite_name: name of the test suite
// name: name of the test // name: name of the test
// type_param the name of the test's type parameter, or NULL if // type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test. // this is not a typed or a type-parameterized test.
// value_param text representation of the test's value parameter, // value_param: text representation of the test's value parameter,
// or NULL if this is not a type-parameterized test. // or NULL if this is not a type-parameterized test.
// code_location: code location where the test is defined // code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class // fixture_class_id: ID of the test fixture class
...@@ -566,8 +590,6 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo( ...@@ -566,8 +590,6 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
// and returns false. None of pstr, *pstr, and prefix can be NULL. // and returns false. None of pstr, *pstr, and prefix can be NULL.
GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
...@@ -607,8 +629,9 @@ class GTEST_API_ TypedTestSuitePState { ...@@ -607,8 +629,9 @@ class GTEST_API_ TypedTestSuitePState {
// Verifies that registered_tests match the test names in // Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or // defined_test_names_; returns registered_tests if successful, or
// aborts the program otherwise. // aborts the program otherwise.
const char* VerifyRegisteredTestNames( const char* VerifyRegisteredTestNames(const char* test_suite_name,
const char* file, int line, const char* registered_tests); const char* file, int line,
const char* registered_tests);
private: private:
typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap; typedef ::std::map<std::string, CodeLocation> RegisteredTestsMap;
...@@ -662,7 +685,7 @@ struct NameGeneratorSelector { ...@@ -662,7 +685,7 @@ struct NameGeneratorSelector {
}; };
template <typename NameGenerator> template <typename NameGenerator>
void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {} void GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}
template <typename NameGenerator, typename Types> template <typename NameGenerator, typename Types>
void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) { void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
...@@ -729,7 +752,7 @@ class TypeParameterizedTest { ...@@ -729,7 +752,7 @@ class TypeParameterizedTest {
// The base case for the compile time recursion. // The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, class TestSel> template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, Types0> { class TypeParameterizedTest<Fixture, TestSel, internal::None> {
public: public:
static bool Register(const char* /*prefix*/, const CodeLocation&, static bool Register(const char* /*prefix*/, const CodeLocation&,
const char* /*case_name*/, const char* /*test_names*/, const char* /*case_name*/, const char* /*test_names*/,
...@@ -740,6 +763,11 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> { ...@@ -740,6 +763,11 @@ class TypeParameterizedTest<Fixture, TestSel, Types0> {
} }
}; };
GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
CodeLocation code_location);
GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
const char* case_name);
// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register() // TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()
// registers *all combinations* of 'Tests' and 'Types' with Google // registers *all combinations* of 'Tests' and 'Types' with Google
// Test. The return value is insignificant - we just need to return // Test. The return value is insignificant - we just need to return
...@@ -752,6 +780,7 @@ class TypeParameterizedTestSuite { ...@@ -752,6 +780,7 @@ class TypeParameterizedTestSuite {
const char* test_names, const char* test_names,
const std::vector<std::string>& type_names = const std::vector<std::string>& type_names =
GenerateNames<DefaultNameGenerator, Types>()) { GenerateNames<DefaultNameGenerator, Types>()) {
RegisterTypeParameterizedTestSuiteInstantiation(case_name);
std::string test_name = StripTrailingSpaces( std::string test_name = StripTrailingSpaces(
GetPrefixUntilComma(test_names)); GetPrefixUntilComma(test_names));
if (!state->TestExists(test_name)) { if (!state->TestExists(test_name)) {
...@@ -781,7 +810,7 @@ class TypeParameterizedTestSuite { ...@@ -781,7 +810,7 @@ class TypeParameterizedTestSuite {
// The base case for the compile time recursion. // The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types> template <GTEST_TEMPLATE_ Fixture, typename Types>
class TypeParameterizedTestSuite<Fixture, Templates0, Types> { class TypeParameterizedTestSuite<Fixture, internal::None, Types> {
public: public:
static bool Register(const char* /*prefix*/, const CodeLocation&, static bool Register(const char* /*prefix*/, const CodeLocation&,
const TypedTestSuitePState* /*state*/, const TypedTestSuitePState* /*state*/,
...@@ -792,8 +821,6 @@ class TypeParameterizedTestSuite<Fixture, Templates0, Types> { ...@@ -792,8 +821,6 @@ class TypeParameterizedTestSuite<Fixture, Templates0, Types> {
} }
}; };
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// Returns the current OS stack trace as an std::string. // Returns the current OS stack trace as an std::string.
// //
// The maximum number of stack frames to be included is specified by // The maximum number of stack frames to be included is specified by
...@@ -825,6 +852,16 @@ struct GTEST_API_ ConstCharPtr { ...@@ -825,6 +852,16 @@ struct GTEST_API_ ConstCharPtr {
const char* value; const char* value;
}; };
// Helper for declaring std::string within 'if' statement
// in pre C++17 build environment.
struct TrueWithString {
TrueWithString() = default;
explicit TrueWithString(const char* str) : value(str) {}
explicit TrueWithString(const std::string& str) : value(str) {}
explicit operator bool() const { return true; }
std::string value;
};
// A simple Linear Congruential Generator for generating random // A simple Linear Congruential Generator for generating random
// numbers with a uniform distribution. Unlike rand() and srand(), it // numbers with a uniform distribution. Unlike rand() and srand(), it
// doesn't use global state (and therefore can't interfere with user // doesn't use global state (and therefore can't interfere with user
...@@ -832,18 +869,18 @@ struct GTEST_API_ ConstCharPtr { ...@@ -832,18 +869,18 @@ struct GTEST_API_ ConstCharPtr {
// but it's good enough for our purposes. // but it's good enough for our purposes.
class GTEST_API_ Random { class GTEST_API_ Random {
public: public:
static const UInt32 kMaxRange = 1u << 31; static const uint32_t kMaxRange = 1u << 31;
explicit Random(UInt32 seed) : state_(seed) {} explicit Random(uint32_t seed) : state_(seed) {}
void Reseed(UInt32 seed) { state_ = seed; } void Reseed(uint32_t seed) { state_ = seed; }
// Generates a random number from [0, range). Crashes if 'range' is // Generates a random number from [0, range). Crashes if 'range' is
// 0 or greater than kMaxRange. // 0 or greater than kMaxRange.
UInt32 Generate(UInt32 range); uint32_t Generate(uint32_t range);
private: private:
UInt32 state_; uint32_t state_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
}; };
...@@ -851,12 +888,34 @@ class GTEST_API_ Random { ...@@ -851,12 +888,34 @@ class GTEST_API_ Random {
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
typename std::remove_const<typename std::remove_reference<T>::type>::type typename std::remove_const<typename std::remove_reference<T>::type>::type
// IsAProtocolMessage<T>::value is a compile-time bool constant that's // HasDebugStringAndShortDebugString<T>::value is a compile-time bool constant
// true if and only if T is type proto2::Message or a subclass of it. // that's true if and only if T has methods DebugString() and ShortDebugString()
// that return std::string.
template <typename T> template <typename T>
struct IsAProtocolMessage class HasDebugStringAndShortDebugString {
: public bool_constant< private:
std::is_convertible<const T*, const ::proto2::Message*>::value> {}; template <typename C>
static auto CheckDebugString(C*) -> typename std::is_same<
std::string, decltype(std::declval<const C>().DebugString())>::type;
template <typename>
static std::false_type CheckDebugString(...);
template <typename C>
static auto CheckShortDebugString(C*) -> typename std::is_same<
std::string, decltype(std::declval<const C>().ShortDebugString())>::type;
template <typename>
static std::false_type CheckShortDebugString(...);
using HasDebugStringType = decltype(CheckDebugString<T>(nullptr));
using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr));
public:
static constexpr bool value =
HasDebugStringType::value && HasShortDebugStringType::value;
};
template <typename T>
constexpr bool HasDebugStringAndShortDebugString<T>::value;
// When the compiler sees expression IsContainerTest<C>(0), if C is an // When the compiler sees expression IsContainerTest<C>(0), if C is an
// STL-style container class, the first overload of IsContainerTest // STL-style container class, the first overload of IsContainerTest
...@@ -1092,8 +1151,6 @@ class NativeArray { ...@@ -1092,8 +1151,6 @@ class NativeArray {
const Element* array_; const Element* array_;
size_t size_; size_t size_;
void (NativeArray::*clone_)(const Element*, size_t); void (NativeArray::*clone_)(const Element*, size_t);
GTEST_DISALLOW_ASSIGN_(NativeArray);
}; };
// Backport of std::index_sequence. // Backport of std::index_sequence.
...@@ -1117,32 +1174,44 @@ struct DoubleSequence<false, IndexSequence<I...>, sizeofT> { ...@@ -1117,32 +1174,44 @@ struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
// Backport of std::make_index_sequence. // Backport of std::make_index_sequence.
// It uses O(ln(N)) instantiation depth. // It uses O(ln(N)) instantiation depth.
template <size_t N> template <size_t N>
struct MakeIndexSequence struct MakeIndexSequenceImpl
: DoubleSequence<N % 2 == 1, typename MakeIndexSequence<N / 2>::type, : DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type,
N / 2>::type {}; N / 2>::type {};
template <> template <>
struct MakeIndexSequence<0> : IndexSequence<> {}; struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
template <size_t N>
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type;
// FIXME: This implementation of ElemFromList is O(1) in instantiation depth, template <typename... T>
// but it is O(N^2) in total instantiations. Not sure if this is the best using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type;
// tradeoff, as it will make it somewhat slow to compile.
template <typename T, size_t, size_t> template <size_t>
struct ElemFromListImpl {}; struct Ignore {
Ignore(...); // NOLINT
};
template <typename T, size_t I> template <typename>
struct ElemFromListImpl<T, I, I> { struct ElemFromListImpl;
using type = T; template <size_t... I>
struct ElemFromListImpl<IndexSequence<I...>> {
// We make Ignore a template to solve a problem with MSVC.
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
// MSVC doesn't understand how to deal with that pack expansion.
// Use `0 * I` to have a single instantiation of Ignore.
template <typename R>
static R Apply(Ignore<0 * I>..., R (*)(), ...);
}; };
// Get the Nth element from T... template <size_t N, typename... T>
// It uses O(1) instantiation depth. struct ElemFromList {
template <size_t N, typename I, typename... T> using type =
struct ElemFromList; decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
static_cast<T (*)()>(nullptr)...));
};
template <size_t N, size_t... I, typename... T> struct FlatTupleConstructTag {};
struct ElemFromList<N, IndexSequence<I...>, T...>
: ElemFromListImpl<T, N, I>... {};
template <typename... T> template <typename... T>
class FlatTuple; class FlatTuple;
...@@ -1152,11 +1221,11 @@ struct FlatTupleElemBase; ...@@ -1152,11 +1221,11 @@ struct FlatTupleElemBase;
template <typename... T, size_t I> template <typename... T, size_t I>
struct FlatTupleElemBase<FlatTuple<T...>, I> { struct FlatTupleElemBase<FlatTuple<T...>, I> {
using value_type = using value_type = typename ElemFromList<I, T...>::type;
typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type,
T...>::type;
FlatTupleElemBase() = default; FlatTupleElemBase() = default;
explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {} template <typename Arg>
explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)
: value(std::forward<Arg>(t)) {}
value_type value; value_type value;
}; };
...@@ -1168,13 +1237,35 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> ...@@ -1168,13 +1237,35 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
: FlatTupleElemBase<FlatTuple<T...>, Idx>... { : FlatTupleElemBase<FlatTuple<T...>, Idx>... {
using Indices = IndexSequence<Idx...>; using Indices = IndexSequence<Idx...>;
FlatTupleBase() = default; FlatTupleBase() = default;
explicit FlatTupleBase(T... t) template <typename... Args>
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {} explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
: FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},
std::forward<Args>(args))... {}
template <size_t I>
const typename ElemFromList<I, T...>::type& Get() const {
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
}
template <size_t I>
typename ElemFromList<I, T...>::type& Get() {
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
}
template <typename F>
auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
return std::forward<F>(f)(Get<Idx>()...);
}
template <typename F>
auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
return std::forward<F>(f)(Get<Idx>()...);
}
}; };
// Analog to std::tuple but with different tradeoffs. // Analog to std::tuple but with different tradeoffs.
// This class minimizes the template instantiation depth, thus allowing more // This class minimizes the template instantiation depth, thus allowing more
// elements that std::tuple would. std::tuple has been seen to require an // elements than std::tuple would. std::tuple has been seen to require an
// instantiation depth of more than 10x the number of elements in some // instantiation depth of more than 10x the number of elements in some
// implementations. // implementations.
// FlatTuple and ElemFromList are not recursive and have a fixed depth // FlatTuple and ElemFromList are not recursive and have a fixed depth
...@@ -1185,21 +1276,17 @@ template <typename... T> ...@@ -1185,21 +1276,17 @@ template <typename... T>
class FlatTuple class FlatTuple
: private FlatTupleBase<FlatTuple<T...>, : private FlatTupleBase<FlatTuple<T...>,
typename MakeIndexSequence<sizeof...(T)>::type> { typename MakeIndexSequence<sizeof...(T)>::type> {
using Indices = typename FlatTuple::FlatTupleBase::Indices; using Indices = typename FlatTupleBase<
FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices;
public: public:
FlatTuple() = default; FlatTuple() = default;
explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {} template <typename... Args>
explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)
template <size_t I> : FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}
const typename ElemFromList<I, Indices, T...>::type& Get() const {
return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
template <size_t I> using FlatTuple::FlatTupleBase::Apply;
typename ElemFromList<I, Indices, T...>::type& Get() { using FlatTuple::FlatTupleBase::Get;
return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
}; };
// Utility functions to be called with static_assert to induce deprecation // Utility functions to be called with static_assert to induce deprecation
...@@ -1232,6 +1319,22 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } ...@@ -1232,6 +1319,22 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
namespace std {
// Some standard library implementations use `struct tuple_size` and some use
// `class tuple_size`. Clang warns about the mismatch.
// https://reviews.llvm.org/D55466
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmismatched-tags"
#endif
template <typename... Ts>
struct tuple_size<testing::internal::FlatTuple<Ts...>>
: std::integral_constant<size_t, sizeof...(Ts)> {};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
} // namespace std
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ #define GTEST_MESSAGE_AT_(file, line, message, result_type) \
::testing::internal::AssertHelper(result_type, file, line, message) \ ::testing::internal::AssertHelper(result_type, file, line, message) \
= ::testing::Message() = ::testing::Message()
...@@ -1254,48 +1357,122 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } ...@@ -1254,48 +1357,122 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
// Suppress MSVC warning 4072 (unreachable code) for the code following // Suppress MSVC warning 4072 (unreachable code) for the code following
// statement if it returns or throws (or doesn't return or throw in some // statement if it returns or throws (or doesn't return or throw in some
// situations). // situations).
// NOTE: The "else" is important to keep this expansion to prevent a top-level
// "else" from attaching to our "if".
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
if (::testing::internal::AlwaysTrue()) { statement; } if (::testing::internal::AlwaysTrue()) { \
statement; \
} else /* NOLINT */ \
static_assert(true, "") // User must have a semicolon after expansion.
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ #if GTEST_HAS_EXCEPTIONS
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::ConstCharPtr gtest_msg = "") { \ namespace testing {
bool gtest_caught_expected = false; \ namespace internal {
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ class NeverThrown {
} \ public:
catch (expected_exception const&) { \ const char* what() const noexcept {
gtest_caught_expected = true; \ return "this exception should never be thrown";
} \ }
catch (...) { \ };
gtest_msg.value = \
"Expected: " #statement " throws an exception of type " \ } // namespace internal
#expected_exception ".\n Actual: it throws a different type."; \ } // namespace testing
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \ #if GTEST_HAS_RTTI
if (!gtest_caught_expected) { \
gtest_msg.value = \ #define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))
"Expected: " #statement " throws an exception of type " \
#expected_exception ".\n Actual: it throws nothing."; \ #else // GTEST_HAS_RTTI
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \ #define GTEST_EXCEPTION_TYPE_(e) \
} else \ std::string { "an std::exception-derived error" }
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
fail(gtest_msg.value) #endif // GTEST_HAS_RTTI
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (typename std::conditional< \
std::is_same<typename std::remove_cv<typename std::remove_reference< \
expected_exception>::type>::type, \
std::exception>::value, \
const ::testing::internal::NeverThrown&, const std::exception&>::type \
e) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)
#endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::TrueWithString gtest_msg{}) { \
bool gtest_caught_expected = false; \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (expected_exception const&) { \
gtest_caught_expected = true; \
} \
GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (...) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws a different type."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
if (!gtest_caught_expected) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws nothing."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
} else /*NOLINT*/ \
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \
: fail(gtest_msg.value.c_str())
#if GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
catch (std::exception const& e) { \
gtest_msg.value = "it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()
#endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_(statement, fail) \ #define GTEST_TEST_NO_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \ if (::testing::internal::TrueWithString gtest_msg{}) { \
try { \ try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \ } \
GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
catch (...) { \ catch (...) { \
gtest_msg.value = "it throws."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
} \ } \
} else \ } else \
GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
fail("Expected: " #statement " doesn't throw an exception.\n" \ fail(("Expected: " #statement " doesn't throw an exception.\n" \
" Actual: it throws.") " Actual: " + gtest_msg.value).c_str())
#define GTEST_TEST_ANY_THROW_(statement, fail) \ #define GTEST_TEST_ANY_THROW_(statement, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
...@@ -1318,7 +1495,7 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } ...@@ -1318,7 +1495,7 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
// Implements Boolean test assertions such as EXPECT_TRUE. expression can be // Implements Boolean test assertions such as EXPECT_TRUE. expression can be
// either a boolean expression or an AssertionResult. text is a textual // either a boolean expression or an AssertionResult. text is a textual
// represenation of expression as it was passed into the EXPECT_TRUE. // representation of expression as it was passed into the EXPECT_TRUE.
#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar_ = \ if (const ::testing::AssertionResult gtest_ar_ = \
...@@ -1355,13 +1532,16 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } ...@@ -1355,13 +1532,16 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
: public parent_class { \ : public parent_class { \
public: \ public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \
~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
\ \
private: \ private: \
virtual void TestBody(); \ void TestBody() override; \
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
}; \ }; \
\ \
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
...@@ -1377,4 +1557,4 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } ...@@ -1377,4 +1557,4 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
test_suite_name, test_name)>); \ test_suite_name, test_name)>); \
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <ctype.h> #include <ctype.h>
...@@ -42,12 +42,14 @@ ...@@ -42,12 +42,14 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <tuple> #include <tuple>
#include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h" #include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h"
namespace testing { namespace testing {
// Input to a parameterized test name generator, describing a test parameter. // Input to a parameterized test name generator, describing a test parameter.
...@@ -457,7 +459,7 @@ class ParameterizedTestSuiteInfoBase { ...@@ -457,7 +459,7 @@ class ParameterizedTestSuiteInfoBase {
// Base part of test suite name for display purposes. // Base part of test suite name for display purposes.
virtual const std::string& GetTestSuiteName() const = 0; virtual const std::string& GetTestSuiteName() const = 0;
// Test case id to verify identity. // Test suite id to verify identity.
virtual TypeId GetTestSuiteTypeId() const = 0; virtual TypeId GetTestSuiteTypeId() const = 0;
// UnitTest class invokes this method to register tests in this // UnitTest class invokes this method to register tests in this
// test suite right before running them in RUN_ALL_TESTS macro. // test suite right before running them in RUN_ALL_TESTS macro.
...@@ -472,6 +474,17 @@ class ParameterizedTestSuiteInfoBase { ...@@ -472,6 +474,17 @@ class ParameterizedTestSuiteInfoBase {
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase); GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
}; };
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Report a the name of a test_suit as safe to ignore
// as the side effect of construction of this type.
struct GTEST_API_ MarkAsIgnored {
explicit MarkAsIgnored(const char* test_suite);
};
GTEST_API_ void InsertSyntheticTestCase(const std::string& name,
CodeLocation location, bool has_test_p);
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
// //
// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P // ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
...@@ -494,11 +507,11 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -494,11 +507,11 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
CodeLocation code_location) CodeLocation code_location)
: test_suite_name_(name), code_location_(code_location) {} : test_suite_name_(name), code_location_(code_location) {}
// Test case base name for display purposes. // Test suite base name for display purposes.
const std::string& GetTestSuiteName() const override { const std::string& GetTestSuiteName() const override {
return test_suite_name_; return test_suite_name_;
} }
// Test case id to verify identity. // Test suite id to verify identity.
TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); } TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
// TEST_P macro uses AddTestPattern() to record information // TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure. // about a single test in a LocalTestInfo structure.
...@@ -507,9 +520,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -507,9 +520,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test suite base name and DoBar is test base name. // test suite base name and DoBar is test base name.
void AddTestPattern(const char* test_suite_name, const char* test_base_name, void AddTestPattern(const char* test_suite_name, const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) { TestMetaFactoryBase<ParamType>* meta_factory,
tests_.push_back(std::shared_ptr<TestInfo>( CodeLocation code_location) {
new TestInfo(test_suite_name, test_base_name, meta_factory))); tests_.push_back(std::shared_ptr<TestInfo>(new TestInfo(
test_suite_name, test_base_name, meta_factory, code_location)));
} }
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator. // about a generator.
...@@ -522,11 +536,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -522,11 +536,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
return 0; // Return value used only to run this method in namespace scope. return 0; // Return value used only to run this method in namespace scope.
} }
// UnitTest class invokes this method to register tests in this test suite // UnitTest class invokes this method to register tests in this test suite
// test suites right before running tests in RUN_ALL_TESTS macro. // right before running tests in RUN_ALL_TESTS macro.
// This method should not be called more than once on any single // This method should not be called more than once on any single
// instance of a ParameterizedTestSuiteInfoBase derived class. // instance of a ParameterizedTestSuiteInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more than once. // UnitTest has a guard to prevent from calling this method more than once.
void RegisterTests() override { void RegisterTests() override {
bool generated_instantiations = false;
for (typename TestInfoContainer::iterator test_it = tests_.begin(); for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) { test_it != tests_.end(); ++test_it) {
std::shared_ptr<TestInfo> test_info = *test_it; std::shared_ptr<TestInfo> test_info = *test_it;
...@@ -549,6 +565,8 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -549,6 +565,8 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
for (typename ParamGenerator<ParamType>::iterator param_it = for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin(); generator.begin();
param_it != generator.end(); ++param_it, ++i) { param_it != generator.end(); ++param_it, ++i) {
generated_instantiations = true;
Message test_name_stream; Message test_name_stream;
std::string param_name = name_func( std::string param_name = name_func(
...@@ -572,7 +590,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -572,7 +590,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
MakeAndRegisterTestInfo( MakeAndRegisterTestInfo(
test_suite_name.c_str(), test_name_stream.GetString().c_str(), test_suite_name.c_str(), test_name_stream.GetString().c_str(),
nullptr, // No type parameter. nullptr, // No type parameter.
PrintToString(*param_it).c_str(), code_location_, PrintToString(*param_it).c_str(), test_info->code_location,
GetTestSuiteTypeId(), GetTestSuiteTypeId(),
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line), SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line), SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
...@@ -580,6 +598,12 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -580,6 +598,12 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
} // for param_it } // for param_it
} // for gen_it } // for gen_it
} // for test_it } // for test_it
if (!generated_instantiations) {
// There are no generaotrs, or they all generate nothing ...
InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
!tests_.empty());
}
} // RegisterTests } // RegisterTests
private: private:
...@@ -587,14 +611,17 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -587,14 +611,17 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// with TEST_P macro. // with TEST_P macro.
struct TestInfo { struct TestInfo {
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name, TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
TestMetaFactoryBase<ParamType>* a_test_meta_factory) TestMetaFactoryBase<ParamType>* a_test_meta_factory,
CodeLocation a_code_location)
: test_suite_base_name(a_test_suite_base_name), : test_suite_base_name(a_test_suite_base_name),
test_base_name(a_test_base_name), test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory) {} test_meta_factory(a_test_meta_factory),
code_location(a_code_location) {}
const std::string test_suite_base_name; const std::string test_suite_base_name;
const std::string test_base_name; const std::string test_base_name;
const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
const CodeLocation code_location;
}; };
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >; using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
// Records data received from INSTANTIATE_TEST_SUITE_P macros: // Records data received from INSTANTIATE_TEST_SUITE_P macros:
...@@ -627,7 +654,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { ...@@ -627,7 +654,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// Check for invalid characters // Check for invalid characters
for (std::string::size_type index = 0; index < name.size(); ++index) { for (std::string::size_type index = 0; index < name.size(); ++index) {
if (!isalnum(name[index]) && name[index] != '_') if (!IsAlNum(name[index]) && name[index] != '_')
return false; return false;
} }
...@@ -717,6 +744,34 @@ class ParameterizedTestSuiteRegistry { ...@@ -717,6 +744,34 @@ class ParameterizedTestSuiteRegistry {
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry); GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
}; };
// Keep track of what type-parameterized test suite are defined and
// where as well as which are intatiated. This allows susequently
// identifying suits that are defined but never used.
class TypeParameterizedTestSuiteRegistry {
public:
// Add a suite definition
void RegisterTestSuite(const char* test_suite_name,
CodeLocation code_location);
// Add an instantiation of a suit.
void RegisterInstantiation(const char* test_suite_name);
// For each suit repored as defined but not reported as instantiation,
// emit a test that reports that fact (configurably, as an error).
void CheckForInstantiations();
private:
struct TypeParameterizedTestSuiteInfo {
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
: code_location(c), instantiated(false) {}
CodeLocation code_location;
bool instantiated;
};
std::map<std::string, TypeParameterizedTestSuiteInfo> suites_;
};
} // namespace internal } // namespace internal
// Forward declarations of ValuesIn(), which is implemented in // Forward declarations of ValuesIn(), which is implemented in
...@@ -728,10 +783,15 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn( ...@@ -728,10 +783,15 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
namespace internal { namespace internal {
// Used in the Values() function to provide polymorphic capabilities. // Used in the Values() function to provide polymorphic capabilities.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4100)
#endif
template <typename... Ts> template <typename... Ts>
class ValueArray { class ValueArray {
public: public:
ValueArray(Ts... v) : v_{std::move(v)...} {} explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
template <typename T> template <typename T>
operator ParamGenerator<T>() const { // NOLINT operator ParamGenerator<T>() const { // NOLINT
...@@ -747,6 +807,10 @@ class ValueArray { ...@@ -747,6 +807,10 @@ class ValueArray {
FlatTuple<Ts...> v_; FlatTuple<Ts...> v_;
}; };
#ifdef _MSC_VER
#pragma warning(pop)
#endif
template <typename... T> template <typename... T>
class CartesianProductGenerator class CartesianProductGenerator
: public ParamGeneratorInterface<::std::tuple<T...>> { : public ParamGeneratorInterface<::std::tuple<T...>> {
...@@ -880,4 +944,4 @@ class CartesianProductHolder { ...@@ -880,4 +944,4 @@ class CartesianProductHolder {
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
// This header file defines the GTEST_OS_* macro. // This header file defines the GTEST_OS_* macro.
// It is separate from gtest-port.h so that custom/gtest-port.h can include it. // It is separate from gtest-port.h so that custom/gtest-port.h can include it.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
// Determines the platform on which Google Test is compiled. // Determines the platform on which Google Test is compiled.
#ifdef __CYGWIN__ #ifdef __CYGWIN__
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
# define GTEST_OS_OS2 1 # define GTEST_OS_OS2 1
#elif defined __APPLE__ #elif defined __APPLE__
# define GTEST_OS_MAC 1 # define GTEST_OS_MAC 1
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE # if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1 # define GTEST_OS_IOS 1
# endif # endif
...@@ -102,6 +103,12 @@ ...@@ -102,6 +103,12 @@
# define GTEST_OS_QNX 1 # define GTEST_OS_QNX 1
#elif defined(__HAIKU__) #elif defined(__HAIKU__)
#define GTEST_OS_HAIKU 1 #define GTEST_OS_HAIKU 1
#elif defined ESP8266
#define GTEST_OS_ESP8266 1
#elif defined ESP32
#define GTEST_OS_ESP32 1
#elif defined(__XTENSA__)
#define GTEST_OS_XTENSA 1
#endif // __CYGWIN__ #endif // __CYGWIN__
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
...@@ -40,8 +40,8 @@ ...@@ -40,8 +40,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
// Environment-describing macros // Environment-describing macros
// ----------------------------- // -----------------------------
...@@ -190,13 +190,27 @@ ...@@ -190,13 +190,27 @@
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a
// variable don't have to be used. // variable don't have to be used.
// GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_ASSIGN_ - disables copy operator=.
// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=.
// GTEST_DISALLOW_MOVE_ASSIGN_ - disables move operator=.
// GTEST_DISALLOW_MOVE_AND_ASSIGN_ - disables move ctor and operator=.
// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used.
// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
// suppressed (constant conditional). // suppressed (constant conditional).
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
// is suppressed. // is suppressed.
// GTEST_INTERNAL_HAS_ANY - for enabling UniversalPrinter<std::any> or
// UniversalPrinter<absl::any> specializations.
// GTEST_INTERNAL_HAS_OPTIONAL - for enabling UniversalPrinter<std::optional>
// or
// UniversalPrinter<absl::optional>
// specializations.
// GTEST_INTERNAL_HAS_STRING_VIEW - for enabling Matcher<std::string_view> or
// Matcher<absl::string_view>
// specializations.
// GTEST_INTERNAL_HAS_VARIANT - for enabling UniversalPrinter<std::variant> or
// UniversalPrinter<absl::variant>
// specializations.
// //
// Synchronization: // Synchronization:
// Mutex, MutexLock, ThreadLocal, GetThreadCount() // Mutex, MutexLock, ThreadLocal, GetThreadCount()
...@@ -223,8 +237,7 @@ ...@@ -223,8 +237,7 @@
// //
// Integer types: // Integer types:
// TypeWithSize - maps an integer to a int type. // TypeWithSize - maps an integer to a int type.
// Int32, UInt32, Int64, UInt64, TimeInMillis // TimeInMillis - integers of known sizes.
// - integers of known sizes.
// BiggestInt - the biggest signed integer type. // BiggestInt - the biggest signed integer type.
// //
// Command-line utilities: // Command-line utilities:
...@@ -235,7 +248,7 @@ ...@@ -235,7 +248,7 @@
// Environment variable utilities: // Environment variable utilities:
// GetEnv() - gets the value of an environment variable. // GetEnv() - gets the value of an environment variable.
// BoolFromGTestEnv() - parses a bool environment variable. // BoolFromGTestEnv() - parses a bool environment variable.
// Int32FromGTestEnv() - parses an Int32 environment variable. // Int32FromGTestEnv() - parses an int32_t environment variable.
// StringFromGTestEnv() - parses a string environment variable. // StringFromGTestEnv() - parses a string environment variable.
// //
// Deprecation warnings: // Deprecation warnings:
...@@ -248,7 +261,10 @@ ...@@ -248,7 +261,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <memory>
#include <cerrno>
#include <cstdint>
#include <limits>
#include <type_traits> #include <type_traits>
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
...@@ -261,16 +277,15 @@ ...@@ -261,16 +277,15 @@
# include <TargetConditionals.h> # include <TargetConditionals.h>
#endif #endif
#include <algorithm> // NOLINT #include <iostream> // NOLINT
#include <iostream> // NOLINT #include <locale>
#include <sstream> // NOLINT #include <memory>
#include <string> // NOLINT #include <string> // NOLINT
#include <tuple> #include <tuple>
#include <utility>
#include <vector> // NOLINT #include <vector> // NOLINT
#include "gtest/internal/gtest-port-arch.h"
#include "gtest/internal/custom/gtest-port.h" #include "gtest/internal/custom/gtest-port.h"
#include "gtest/internal/gtest-port-arch.h"
#if !defined(GTEST_DEV_EMAIL_) #if !defined(GTEST_DEV_EMAIL_)
# define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" # define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
...@@ -344,6 +359,10 @@ typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION; ...@@ -344,6 +359,10 @@ typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. // WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.
typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif #endif
#elif GTEST_OS_XTENSA
#include <unistd.h>
// Xtensa toolchains define strcasecmp in the string.h header instead of
// strings.h. string.h is already included.
#else #else
// This assumes that non-Windows OSes provide unistd.h. For OSes where this // This assumes that non-Windows OSes provide unistd.h. For OSes where this
// is not the case, we need to include headers that provide the functions // is not the case, we need to include headers that provide the functions
...@@ -364,7 +383,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; ...@@ -364,7 +383,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// On Android, <regex.h> is only available starting with Gingerbread. // On Android, <regex.h> is only available starting with Gingerbread.
# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) # define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9)
# else # else
# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) #define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA)
# endif # endif
#endif #endif
...@@ -441,15 +460,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; ...@@ -441,15 +460,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# endif // defined(_MSC_VER) || defined(__BORLANDC__) # endif // defined(_MSC_VER) || defined(__BORLANDC__)
#endif // GTEST_HAS_EXCEPTIONS #endif // GTEST_HAS_EXCEPTIONS
#if !defined(GTEST_HAS_STD_STRING)
// Even though we don't use this macro any longer, we keep it in case
// some clients still depend on it.
# define GTEST_HAS_STD_STRING 1
#elif !GTEST_HAS_STD_STRING
// The user told us that ::std::string isn't available.
# error "::std::string isn't available."
#endif // !defined(GTEST_HAS_STD_STRING)
#ifndef GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_STD_WSTRING
// The user didn't tell us whether ::std::wstring is available, so we need // The user didn't tell us whether ::std::wstring is available, so we need
// to figure it out. // to figure it out.
...@@ -458,7 +468,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; ...@@ -458,7 +468,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// no support for it at least as recent as Froyo (2.2). // no support for it at least as recent as Froyo (2.2).
#define GTEST_HAS_STD_WSTRING \ #define GTEST_HAS_STD_WSTRING \
(!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
GTEST_OS_HAIKU)) GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA))
#endif // GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_STD_WSTRING
...@@ -582,7 +592,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; ...@@ -582,7 +592,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_HAS_STREAM_REDIRECTION #ifndef GTEST_HAS_STREAM_REDIRECTION
// By default, we assume that stream redirection is supported on all // By default, we assume that stream redirection is supported on all
// platforms except known mobile ones. // platforms except known mobile ones.
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
# define GTEST_HAS_STREAM_REDIRECTION 0 # define GTEST_HAS_STREAM_REDIRECTION 0
# else # else
# define GTEST_HAS_STREAM_REDIRECTION 1 # define GTEST_HAS_STREAM_REDIRECTION 1
...@@ -676,16 +687,27 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; ...@@ -676,16 +687,27 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#endif #endif
// A macro to disallow operator= // A macro to disallow copy operator=
// This should be used in the private: declarations for a class. // This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_ASSIGN_(type) \ #define GTEST_DISALLOW_ASSIGN_(type) \
void operator=(type const &) = delete type& operator=(type const &) = delete
// A macro to disallow copy constructor and operator= // A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class. // This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \ #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
type(type const &) = delete; \ type(type const&) = delete; \
GTEST_DISALLOW_ASSIGN_(type) type& operator=(type const&) = delete
// A macro to disallow move operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_MOVE_ASSIGN_(type) \
type& operator=(type &&) noexcept = delete
// A macro to disallow move constructor and operator=
// This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_MOVE_AND_ASSIGN_(type) \
type(type&&) noexcept = delete; \
type& operator=(type&&) noexcept = delete
// Tell the compiler to warn about unused return values for functions declared // Tell the compiler to warn about unused return values for functions declared
// with this macro. The macro should be used on function declarations // with this macro. The macro should be used on function declarations
...@@ -856,9 +878,6 @@ class Secret; ...@@ -856,9 +878,6 @@ class Secret;
// expression is false, compiler will issue an error containing this identifier. // expression is false, compiler will issue an error containing this identifier.
#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) #define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
// Evaluates to the number of elements in 'array'.
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
// A helper for suppressing warnings on constant condition. It just // A helper for suppressing warnings on constant condition. It just
// returns 'condition'. // returns 'condition'.
GTEST_API_ bool IsTrue(bool condition); GTEST_API_ bool IsTrue(bool condition);
...@@ -915,8 +934,6 @@ class GTEST_API_ RE { ...@@ -915,8 +934,6 @@ class GTEST_API_ RE {
const char* full_pattern_; // For FullMatch(); const char* full_pattern_; // For FullMatch();
# endif # endif
GTEST_DISALLOW_ASSIGN_(RE);
}; };
#endif // GTEST_USES_PCRE #endif // GTEST_USES_PCRE
...@@ -1599,7 +1616,7 @@ class ThreadLocal : public ThreadLocalBase { ...@@ -1599,7 +1616,7 @@ class ThreadLocal : public ThreadLocalBase {
class DefaultValueHolderFactory : public ValueHolderFactory { class DefaultValueHolderFactory : public ValueHolderFactory {
public: public:
DefaultValueHolderFactory() {} DefaultValueHolderFactory() {}
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
...@@ -1608,7 +1625,7 @@ class ThreadLocal : public ThreadLocalBase { ...@@ -1608,7 +1625,7 @@ class ThreadLocal : public ThreadLocalBase {
class InstanceValueHolderFactory : public ValueHolderFactory { class InstanceValueHolderFactory : public ValueHolderFactory {
public: public:
explicit InstanceValueHolderFactory(const T& value) : value_(value) {} explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
virtual ValueHolder* MakeNewHolder() const { ValueHolder* MakeNewHolder() const override {
return new ValueHolder(value_); return new ValueHolder(value_);
} }
...@@ -1808,7 +1825,7 @@ class GTEST_API_ ThreadLocal { ...@@ -1808,7 +1825,7 @@ class GTEST_API_ ThreadLocal {
class DefaultValueHolderFactory : public ValueHolderFactory { class DefaultValueHolderFactory : public ValueHolderFactory {
public: public:
DefaultValueHolderFactory() {} DefaultValueHolderFactory() {}
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } ValueHolder* MakeNewHolder() const override { return new ValueHolder(); }
private: private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
...@@ -1817,7 +1834,7 @@ class GTEST_API_ ThreadLocal { ...@@ -1817,7 +1834,7 @@ class GTEST_API_ ThreadLocal {
class InstanceValueHolderFactory : public ValueHolderFactory { class InstanceValueHolderFactory : public ValueHolderFactory {
public: public:
explicit InstanceValueHolderFactory(const T& value) : value_(value) {} explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
virtual ValueHolder* MakeNewHolder() const { ValueHolder* MakeNewHolder() const override {
return new ValueHolder(value_); return new ValueHolder(value_);
} }
...@@ -1887,18 +1904,12 @@ class GTEST_API_ ThreadLocal { ...@@ -1887,18 +1904,12 @@ class GTEST_API_ ThreadLocal {
// we cannot detect it. // we cannot detect it.
GTEST_API_ size_t GetThreadCount(); GTEST_API_ size_t GetThreadCount();
template <bool B>
using bool_constant = std::integral_constant<bool, B>;
#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.
...@@ -1929,6 +1940,19 @@ inline bool IsUpper(char ch) { ...@@ -1929,6 +1940,19 @@ inline bool IsUpper(char ch) {
inline bool IsXDigit(char ch) { inline bool IsXDigit(char ch) {
return isxdigit(static_cast<unsigned char>(ch)) != 0; return isxdigit(static_cast<unsigned char>(ch)) != 0;
} }
#ifdef __cpp_char8_t
inline bool IsXDigit(char8_t ch) {
return isxdigit(static_cast<unsigned char>(ch)) != 0;
}
#endif
inline bool IsXDigit(char16_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0;
}
inline bool IsXDigit(char32_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0;
}
inline bool IsXDigit(wchar_t ch) { inline bool IsXDigit(wchar_t ch) {
const unsigned char low_byte = static_cast<unsigned char>(ch); const unsigned char low_byte = static_cast<unsigned char>(ch);
return ch == low_byte && isxdigit(low_byte) != 0; return ch == low_byte && isxdigit(low_byte) != 0;
...@@ -1963,16 +1987,16 @@ namespace posix { ...@@ -1963,16 +1987,16 @@ namespace posix {
typedef struct _stat StatStruct; typedef struct _stat StatStruct;
# ifdef __BORLANDC__ # ifdef __BORLANDC__
inline int IsATTY(int fd) { return isatty(fd); } inline int DoIsATTY(int fd) { return isatty(fd); }
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return stricmp(s1, s2); return stricmp(s1, s2);
} }
inline char* StrDup(const char* src) { return strdup(src); } inline char* StrDup(const char* src) { return strdup(src); }
# else // !__BORLANDC__ # else // !__BORLANDC__
# if GTEST_OS_WINDOWS_MOBILE # if GTEST_OS_WINDOWS_MOBILE
inline int IsATTY(int /* fd */) { return 0; } inline int DoIsATTY(int /* fd */) { return 0; }
# else # else
inline int IsATTY(int fd) { return _isatty(fd); } inline int DoIsATTY(int fd) { return _isatty(fd); }
# endif // GTEST_OS_WINDOWS_MOBILE # endif // GTEST_OS_WINDOWS_MOBILE
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return _stricmp(s1, s2); return _stricmp(s1, s2);
...@@ -1993,12 +2017,28 @@ inline bool IsDir(const StatStruct& st) { ...@@ -1993,12 +2017,28 @@ inline bool IsDir(const StatStruct& st) {
} }
# endif // GTEST_OS_WINDOWS_MOBILE # endif // GTEST_OS_WINDOWS_MOBILE
#elif GTEST_OS_ESP8266
typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); }
inline int DoIsATTY(int fd) { return isatty(fd); }
inline int Stat(const char* path, StatStruct* buf) {
// stat function not implemented on ESP8266
return 0;
}
inline int StrCaseCmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2);
}
inline char* StrDup(const char* src) { return strdup(src); }
inline int RmDir(const char* dir) { return rmdir(dir); }
inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#else #else
typedef struct stat StatStruct; typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); } inline int FileNo(FILE* file) { return fileno(file); }
inline int IsATTY(int fd) { return isatty(fd); } inline int DoIsATTY(int fd) { return isatty(fd); }
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2); return strcasecmp(s1, s2);
...@@ -2009,23 +2049,39 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } ...@@ -2009,23 +2049,39 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
inline int IsATTY(int fd) {
// DoIsATTY might change errno (for example ENOTTY in case you redirect stdout
// to a file on Linux), which is unexpected, so save the previous value, and
// restore it after the call.
int savedErrno = errno;
int isAttyValue = DoIsATTY(fd);
errno = savedErrno;
return isAttyValue;
}
// Functions deprecated by MSVC 8.0. // Functions deprecated by MSVC 8.0.
GTEST_DISABLE_MSC_DEPRECATED_PUSH_() GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
inline const char* StrNCpy(char* dest, const char* src, size_t n) {
return strncpy(dest, src, n);
}
// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
// StrError() aren't needed on Windows CE at this time and thus not // StrError() aren't needed on Windows CE at this time and thus not
// defined there. // defined there.
#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \
!GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA
inline int ChDir(const char* dir) { return chdir(dir); } inline int ChDir(const char* dir) { return chdir(dir); }
#endif #endif
inline FILE* FOpen(const char* path, const char* mode) { inline FILE* FOpen(const char* path, const char* mode) {
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
struct wchar_codecvt : public std::codecvt<wchar_t, char, std::mbstate_t> {};
std::wstring_convert<wchar_codecvt> converter;
std::wstring wide_path = converter.from_bytes(path);
std::wstring wide_mode = converter.from_bytes(mode);
return _wfopen(wide_path.c_str(), wide_mode.c_str());
#else // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
return fopen(path, mode); return fopen(path, mode);
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
} }
#if !GTEST_OS_WINDOWS_MOBILE #if !GTEST_OS_WINDOWS_MOBILE
inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
...@@ -2045,8 +2101,9 @@ inline int Close(int fd) { return close(fd); } ...@@ -2045,8 +2101,9 @@ inline int Close(int fd) { return close(fd); }
inline const char* StrError(int errnum) { return strerror(errnum); } inline const char* StrError(int errnum) { return strerror(errnum); }
#endif #endif
inline const char* GetEnv(const char* name) { inline const char* GetEnv(const char* name) {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
// We are on Windows CE, which has no environment variables. GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA
// We are on an embedded platform, which has no environment variables.
static_cast<void>(name); // To prevent 'unused argument' warning. static_cast<void>(name); // To prevent 'unused argument' warning.
return nullptr; return nullptr;
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
...@@ -2088,15 +2145,13 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_() ...@@ -2088,15 +2145,13 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_()
# define GTEST_SNPRINTF_ snprintf # define GTEST_SNPRINTF_ snprintf
#endif #endif
// The maximum number a BiggestInt can represent. This definition // The biggest signed integer type the compiler supports.
// 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 // long long is guaranteed to be at least 64-bits in C++11.
// are not part of standard C++ and numeric_limits doesn't need to be using BiggestInt = long long; // NOLINT
// defined for them.
const BiggestInt kMaxBiggestInt = // The maximum number a BiggestInt can represent.
~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();
// 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
...@@ -2121,40 +2176,27 @@ class TypeWithSize { ...@@ -2121,40 +2176,27 @@ class TypeWithSize {
public: public:
// This prevents the user from using TypeWithSize<N> with incorrect // This prevents the user from using TypeWithSize<N> with incorrect
// values of N. // values of N.
typedef void UInt; using UInt = void;
}; };
// The specialization for size 4. // The specialization for size 4.
template <> template <>
class TypeWithSize<4> { class TypeWithSize<4> {
public: public:
// unsigned int has size 4 in both gcc and MSVC. using Int = std::int32_t;
// using UInt = std::uint32_t;
// As base/basictypes.h doesn't compile on Windows, we cannot use
// uint32, uint64, and etc here.
typedef int Int;
typedef unsigned int UInt;
}; };
// The specialization for size 8. // The specialization for size 8.
template <> template <>
class TypeWithSize<8> { class TypeWithSize<8> {
public: public:
#if GTEST_OS_WINDOWS using Int = std::int64_t;
typedef __int64 Int; using UInt = std::uint64_t;
typedef unsigned __int64 UInt;
#else
typedef long long Int; // NOLINT
typedef unsigned long long UInt; // NOLINT
#endif // GTEST_OS_WINDOWS
}; };
// Integer types of known sizes. // Integer types of known sizes.
typedef TypeWithSize<4>::Int Int32; using TimeInMillis = int64_t; // Represents time in milliseconds.
typedef TypeWithSize<4>::UInt UInt32;
typedef TypeWithSize<8>::Int Int64;
typedef TypeWithSize<8>::UInt UInt64;
typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
// Utilities for command line flags and environment variables. // Utilities for command line flags and environment variables.
...@@ -2173,7 +2215,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. ...@@ -2173,7 +2215,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
// Macros for declaring flags. // Macros for declaring flags.
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) # define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
# define GTEST_DECLARE_int32_(name) \ # define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) GTEST_API_ extern std::int32_t GTEST_FLAG(name)
# define GTEST_DECLARE_string_(name) \ # define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::std::string GTEST_FLAG(name) GTEST_API_ extern ::std::string GTEST_FLAG(name)
...@@ -2181,7 +2223,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. ...@@ -2181,7 +2223,7 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
# define GTEST_DEFINE_bool_(name, default_val, doc) \ # define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GTEST_FLAG(name) = (default_val) GTEST_API_ bool GTEST_FLAG(name) = (default_val)
# define GTEST_DEFINE_int32_(name, default_val, doc) \ # define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) GTEST_API_ std::int32_t GTEST_FLAG(name) = (default_val)
# define GTEST_DEFINE_string_(name, default_val, doc) \ # define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
...@@ -2196,12 +2238,13 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. ...@@ -2196,12 +2238,13 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
// Parses 'str' for a 32-bit signed integer. If successful, writes the result // Parses 'str' for a 32-bit signed integer. If successful, writes the result
// to *value and returns true; otherwise leaves *value unchanged and returns // to *value and returns true; otherwise leaves *value unchanged and returns
// false. // false.
bool ParseInt32(const Message& src_text, const char* str, Int32* value); GTEST_API_ bool ParseInt32(const Message& src_text, const char* str,
int32_t* value);
// Parses a bool/Int32/string from the environment variable // Parses a bool/int32_t/string from the environment variable
// corresponding to the given Google Test flag. // corresponding to the given Google Test flag.
bool BoolFromGTestEnv(const char* flag, bool default_val); bool BoolFromGTestEnv(const char* flag, bool default_val);
GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); GTEST_API_ int32_t Int32FromGTestEnv(const char* flag, int32_t default_val);
std::string OutputFlagAlsoCheckEnvVar(); std::string OutputFlagAlsoCheckEnvVar();
const char* StringFromGTestEnv(const char* flag, const char* default_val); const char* StringFromGTestEnv(const char* flag, const char* default_val);
...@@ -2228,4 +2271,119 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val); ...@@ -2228,4 +2271,119 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val);
#endif // !defined(GTEST_INTERNAL_DEPRECATED) #endif // !defined(GTEST_INTERNAL_DEPRECATED)
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #if GTEST_HAS_ABSL
// Always use absl::any for UniversalPrinter<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_ANY 1
#include "absl/types/any.h"
namespace testing {
namespace internal {
using Any = ::absl::any;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<any>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::any for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_ANY 1
#include <any>
namespace testing {
namespace internal {
using Any = ::std::any;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::any is not
// supported.
#endif // __has_include(<any>) && __cplusplus >= 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL
#if GTEST_HAS_ABSL
// Always use absl::optional for UniversalPrinter<> specializations if
// googletest is built with absl support.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
#include "absl/types/optional.h"
namespace testing {
namespace internal {
template <typename T>
using Optional = ::absl::optional<T>;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<optional>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::optional for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_OPTIONAL 1
#include <optional>
namespace testing {
namespace internal {
template <typename T>
using Optional = ::std::optional<T>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::optional is not
// supported.
#endif // __has_include(<optional>) && __cplusplus >= 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL
#if GTEST_HAS_ABSL
// Always use absl::string_view for Matcher<> specializations if googletest
// is built with absl support.
# define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include "absl/strings/string_view.h"
namespace testing {
namespace internal {
using StringView = ::absl::string_view;
} // namespace internal
} // namespace testing
#else
# ifdef __has_include
# if __has_include(<string_view>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::string_view for Matcher<>
// specializations.
# define GTEST_INTERNAL_HAS_STRING_VIEW 1
#include <string_view>
namespace testing {
namespace internal {
using StringView = ::std::string_view;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::string_view is not
// supported.
# endif // __has_include(<string_view>) && __cplusplus >= 201703L
# endif // __has_include
#endif // GTEST_HAS_ABSL
#if GTEST_HAS_ABSL
// Always use absl::variant for UniversalPrinter<> specializations if googletest
// is built with absl support.
#define GTEST_INTERNAL_HAS_VARIANT 1
#include "absl/types/variant.h"
namespace testing {
namespace internal {
template <typename... T>
using Variant = ::absl::variant<T...>;
} // namespace internal
} // namespace testing
#else
#ifdef __has_include
#if __has_include(<variant>) && __cplusplus >= 201703L
// Otherwise for C++17 and higher use std::variant for UniversalPrinter<>
// specializations.
#define GTEST_INTERNAL_HAS_VARIANT 1
#include <variant>
namespace testing {
namespace internal {
template <typename... T>
using Variant = ::std::variant<T...>;
} // namespace internal
} // namespace testing
// The case where absl is configured NOT to alias std::variant is not supported.
#endif // __has_include(<variant>) && __cplusplus >= 201703L
#endif // __has_include
#endif // GTEST_HAS_ABSL
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__ #ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder. // string.h is not guaranteed to provide strcpy on C++ Builder.
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#endif #endif
#include <string.h> #include <string.h>
#include <cstdint>
#include <string> #include <string>
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
...@@ -148,11 +149,14 @@ class GTEST_API_ String { ...@@ -148,11 +149,14 @@ class GTEST_API_ String {
// Formats an int value as "%02d". // Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2 static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value to given width with leading zeros.
static std::string FormatIntWidthN(int value, int width);
// Formats an int value as "%X". // Formats an int value as "%X".
static std::string FormatHexInt(int value); static std::string FormatHexInt(int value);
// Formats an int value as "%X". // Formats an int value as "%X".
static std::string FormatHexUInt32(UInt32 value); static std::string FormatHexUInt32(uint32_t value);
// Formats a byte as "%02X". // Formats a byte as "%02X".
static std::string FormatByte(unsigned char value); static std::string FormatByte(unsigned char value);
...@@ -168,4 +172,4 @@ GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); ...@@ -168,4 +172,4 @@ GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of type lists we want to support.
// Copyright 2008 Google Inc. // Copyright 2008 Google Inc.
// All Rights Reserved. // All Rights Reserved.
// //
...@@ -29,19 +27,13 @@ $var n = 50 $$ Maximum length of type lists we want to support. ...@@ -29,19 +27,13 @@ $var n = 50 $$ Maximum length of type lists we want to support.
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Type utilities needed for implementing typed and type-parameterized // Type utilities needed for implementing typed and type-parameterized
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // tests.
//
// Currently we support at most $n types in a list, and at most $n
// type-parameterized tests in one type-parameterized test suite.
// Please contact googletestframework@googlegroups.com if you need
// more.
// GOOGLETEST_CM0001 DO NOT DELETE // GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
...@@ -72,116 +64,43 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) { ...@@ -72,116 +64,43 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
return s; return s;
} }
// GetTypeName<T>() returns a human-readable name of type T. #if GTEST_HAS_RTTI
// NB: This function is also used in Google Mock, so don't move it inside of // GetTypeName(const std::type_info&) returns a human-readable name of type T.
// the typed-test-only section below. inline std::string GetTypeName(const std::type_info& type) {
template <typename T> const char* const name = type.name();
std::string GetTypeName() { #if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
# if GTEST_HAS_RTTI
const char* const name = typeid(T).name();
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0; int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name, // gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it. // so we have to demangle it.
# if GTEST_HAS_CXXABI_H_ #if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle; using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_ #endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
const std::string name_str(status == 0 ? readable_name : name); const std::string name_str(status == 0 ? readable_name : name);
free(readable_name); free(readable_name);
return CanonicalizeForStdLibVersioning(name_str); return CanonicalizeForStdLibVersioning(name_str);
# else #else
return name; return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC #endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
}
# else #endif // GTEST_HAS_RTTI
// GetTypeName<T>() returns a human-readable name of type T if and only if
// RTTI is enabled, otherwise it returns a dummy type name.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
#if GTEST_HAS_RTTI
return GetTypeName(typeid(T));
#else
return "<type>"; return "<type>";
#endif // GTEST_HAS_RTTI
# endif // GTEST_HAS_RTTI
} }
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // A unique type indicating an empty node
// A unique type used as the default value for the arguments of class
// template Types. This allows us to simulate variadic templates
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
// support directly.
struct None {}; struct None {};
// The following family of struct and struct templates are used to
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
// represents a type list with N types (T1, T2, ..., and TN) in it.
// Except for Types0, every struct in the family has two member types:
// Head for the first type in the list, and Tail for the rest of the
// list.
// The empty type list.
struct Types0 {};
// Type lists of length 1, 2, 3, and so on.
template <typename T1>
struct Types1 {
typedef T1 Head;
typedef Types0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
struct Types$i {
typedef T1 Head;
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
};
]]
} // namespace internal
// We don't want to require the users to write TypesN<...> directly,
// as that would require them to count the length. Types<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Types<int>
// will appear as Types<int, None, None, ..., None> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Types<T1, ..., TN>, and Google Test will translate
// that to TypesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Types template.
$range i 1..n
template <$for i, [[typename T$i = internal::None]]>
struct Types {
typedef internal::Types$n<$for i, [[T$i]]> type;
};
template <>
struct Types<$for i, [[internal::None]]> {
typedef internal::Types0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[typename T$j]]>
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
typedef internal::Types$i<$for j, [[T$j]]> type;
};
]]
namespace internal {
# define GTEST_TEMPLATE_ template <typename T> class # define GTEST_TEMPLATE_ template <typename T> class
// The template "selector" struct TemplateSel<Tmpl> is used to // The template "selector" struct TemplateSel<Tmpl> is used to
...@@ -203,100 +122,62 @@ struct TemplateSel { ...@@ -203,100 +122,62 @@ struct TemplateSel {
# define GTEST_BIND_(TmplSel, T) \ # define GTEST_BIND_(TmplSel, T) \
TmplSel::template Bind<T>::type TmplSel::template Bind<T>::type
// A unique struct template used as the default value for the template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
// arguments of class template Templates. This allows us to simulate struct Templates {
// variadic templates (e.g. Templates<int>, Templates<int, double>, using Head = TemplateSel<Head_>;
// and etc), which C++ doesn't support directly. using Tail = Templates<Tail_...>;
template <typename T>
struct NoneT {};
// The following family of struct and struct templates are used to
// represent template lists. In particular, TemplatesN<T1, T2, ...,
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
// for Templates0, every struct in the family has two member types:
// Head for the selector of the first template in the list, and Tail
// for the rest of the list.
// The empty template list.
struct Templates0 {};
// Template lists of length 1, 2, 3, and so on.
template <GTEST_TEMPLATE_ T1>
struct Templates1 {
typedef TemplateSel<T1> Head;
typedef Templates0 Tail;
}; };
$range i 2..n template <GTEST_TEMPLATE_ Head_>
struct Templates<Head_> {
$for i [[ using Head = TemplateSel<Head_>;
$range j 1..i using Tail = None;
$range k 2..i
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates$i {
typedef TemplateSel<T1> Head;
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
}; };
// Tuple-like type lists
]] template <typename Head_, typename... Tail_>
struct Types {
// We don't want to require the users to write TemplatesN<...> directly, using Head = Head_;
// as that would require them to count the length. Templates<...> is much using Tail = Types<Tail_...>;
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Templates<list>
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Templates<T1, ..., TN>, and Google Test will translate
// that to TemplatesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Templates template.
$range i 1..n
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
struct Templates {
typedef Templates$n<$for i, [[T$i]]> type;
}; };
template <> template <typename Head_>
struct Templates<$for i, [[NoneT]]> { struct Types<Head_> {
typedef Templates0 type; using Head = Head_;
using Tail = None;
}; };
$range i 1..n-1 // Helper metafunctions to tell apart a single type from types
$for i [[ // generated by ::testing::Types
$range j 1..i template <typename... Ts>
$range k i+1..n struct ProxyTypeList {
template <$for j, [[GTEST_TEMPLATE_ T$j]]> using type = Types<Ts...>;
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
typedef Templates$i<$for j, [[T$j]]> type;
}; };
]] template <typename>
struct is_proxy_type_list : std::false_type {};
// The TypeList template makes it possible to use either a single type template <typename... Ts>
// or a Types<...> list in TYPED_TEST_SUITE() and struct is_proxy_type_list<ProxyTypeList<Ts...>> : std::true_type {};
// INSTANTIATE_TYPED_TEST_SUITE_P().
// Generator which conditionally creates type lists.
// It recognizes if a requested type list should be created
// and prevents creating a new type list nested within another one.
template <typename T> template <typename T>
struct TypeList { struct GenerateTypeList {
typedef Types1<T> type; private:
}; using proxy = typename std::conditional<is_proxy_type_list<T>::value, T,
ProxyTypeList<T>>::type;
$range i 1..n public:
template <$for i, [[typename T$i]]> using type = typename proxy::type;
struct TypeList<Types<$for i, [[T$i]]> > {
typedef typename Types<$for i, [[T$i]]>::type type;
}; };
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal } // namespace internal
template <typename... Ts>
using Types = internal::ProxyTypeList<Ts...>;
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
// prime and determines a next prime number. This interface is used // prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests. // in Google Test samples demonstrating use of parameterized tests.
#ifndef GTEST_SAMPLES_PRIME_TABLES_H_ #ifndef GOOGLETEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_ #define GOOGLETEST_SAMPLES_PRIME_TABLES_H_
#include <algorithm> #include <algorithm>
...@@ -66,11 +66,11 @@ class OnTheFlyPrimeTable : public PrimeTable { ...@@ -66,11 +66,11 @@ class OnTheFlyPrimeTable : public PrimeTable {
} }
int GetNextPrime(int p) const override { int GetNextPrime(int p) const override {
for (int n = p + 1; n > 0; n++) { if (p < 0) return -1;
for (int n = p + 1;; n++) {
if (IsPrime(n)) return n; if (IsPrime(n)) return n;
} }
return -1;
} }
}; };
...@@ -123,4 +123,4 @@ class PreCalculatedPrimeTable : public PrimeTable { ...@@ -123,4 +123,4 @@ class PreCalculatedPrimeTable : public PrimeTable {
void operator=(const PreCalculatedPrimeTable& rhs); void operator=(const PreCalculatedPrimeTable& rhs);
}; };
#endif // GTEST_SAMPLES_PRIME_TABLES_H_ #endif // GOOGLETEST_SAMPLES_PRIME_TABLES_H_
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE1_H_ #ifndef GOOGLETEST_SAMPLES_SAMPLE1_H_
#define GTEST_SAMPLES_SAMPLE1_H_ #define GOOGLETEST_SAMPLES_SAMPLE1_H_
// Returns n! (the factorial of n). For negative n, n! is defined to be 1. // Returns n! (the factorial of n). For negative n, n! is defined to be 1.
int Factorial(int n); int Factorial(int n);
...@@ -38,4 +38,4 @@ int Factorial(int n); ...@@ -38,4 +38,4 @@ int Factorial(int n);
// Returns true if and only if n is a prime number. // Returns true if and only if n is a prime number.
bool IsPrime(int n); bool IsPrime(int n);
#endif // GTEST_SAMPLES_SAMPLE1_H_ #endif // GOOGLETEST_SAMPLES_SAMPLE1_H_
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
// A sample program demonstrating using Google C++ testing framework. // A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE2_H_ #ifndef GOOGLETEST_SAMPLES_SAMPLE2_H_
#define GTEST_SAMPLES_SAMPLE2_H_ #define GOOGLETEST_SAMPLES_SAMPLE2_H_
#include <string.h> #include <string.h>
...@@ -77,5 +77,4 @@ class MyString { ...@@ -77,5 +77,4 @@ class MyString {
void Set(const char* c_string); void Set(const char* c_string);
}; };
#endif // GOOGLETEST_SAMPLES_SAMPLE2_H_
#endif // GTEST_SAMPLES_SAMPLE2_H_
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment