From a178cc7ef73ce7e6e7e688d3d5cbccfc3c1d5d6b Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Thu, 15 Mar 2018 14:31:37 -0400 Subject: [PATCH 1/3] merge, again, IsRecursiveContainer --- .../include/gmock/gmock-spec-builders.h | 1 + googlemock/test/gmock-matchers_test.cc | 1 + googletest/include/gtest/gtest-printers.h | 12 +-- .../include/gtest/internal/gtest-internal.h | 75 +++++++++++++++---- googletest/src/gtest.cc | 4 +- googletest/test/gtest_unittest.cc | 50 +++++++++++++ 6 files changed, 123 insertions(+), 20 deletions(-) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index c1b63014..f8e1c6ab 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -563,6 +563,7 @@ class ExpectationSet { public: // A bidirectional iterator that can read a const element in the set. typedef Expectation::Set::const_iterator const_iterator; + typedef Expectation::Set::iterator iterator; // An object stored in the set. This is an alias of Expectation. typedef Expectation::Set::value_type value_type; diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 829935ef..f7bf2a82 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -4526,6 +4526,7 @@ class Streamlike { class ConstIter; public: typedef ConstIter const_iterator; + typedef ConstIter iterator; typedef T value_type; template diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 2c83c3ff..36f4042a 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -509,17 +509,19 @@ void PrintTo(const T& value, ::std::ostream* os) { // function pointers so that the `*os << p` in the object pointer overload // doesn't cause that warning either. DefaultPrintTo( - WrapPrinterType< - (sizeof(IsContainerTest(0)) == sizeof(IsContainer)) && !IsRecursiveContainer::value - ? kPrintContainer : !is_pointer::value - ? kPrintOther + WrapPrinterType < + (sizeof(IsContainerTest(0)) == sizeof(IsContainer)) && + !IsRecursiveContainer::value + ? kPrintContainer + : !is_pointer::value + ? kPrintOther #if GTEST_LANG_CXX11 : std::is_function::type>::value #else : !internal::ImplicitlyConvertible::value #endif ? kPrintFunctionPointer - : kPrintPointer>(), + : kPrintPointer > (), value, os); } diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index e87f85e6..612f8a4d 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -875,8 +875,11 @@ struct IsAProtocolMessage // a container class by checking the type of IsContainerTest(0). // The value of the expression is insignificant. // -// Note that we look for both C::iterator and C::const_iterator. The -// reason is that C++ injects the name of a class as a member of the +// In C++11 mode we check the existence of a const_iterator and that an +// iterator is properly implemented for the container. +// +// For pre-C++11 that we look for both C::iterator and C::const_iterator. +// The reason is that C++ injects the name of a class as a member of the // class itself (e.g. you can refer to class iterator as either // 'iterator' or 'iterator::iterator'). If we look for C::iterator // only, for example, we would mistakenly think that a class named @@ -886,20 +889,52 @@ struct IsAProtocolMessage // IsContainerTest(typename C::const_iterator*) and // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. typedef int IsContainer; +#if GTEST_LANG_CXX11 +template ().begin()), + class = decltype(::std::declval().end()), + class = decltype(++::std::declval()), + class = decltype(*::std::declval()), + class = typename C::const_iterator> +IsContainer IsContainerTest(int /* dummy */) { + return 0; +} +#else template IsContainer IsContainerTest(int /* dummy */, typename C::iterator* /* it */ = NULL, typename C::const_iterator* /* const_it */ = NULL) { return 0; } +#endif // GTEST_LANG_CXX11 typedef char IsNotContainer; template IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } -template (0)) == sizeof(IsContainer) -> +// Trait to detect whether a type T is a hash table. +// The heuristic used is that the type contains an inner type `hasher` and does +// not contain an inner type `reverse_iterator`. +// If the container is iterable in reverse, then order might actually matter. +template +struct IsHashTable { + private: + template + static char test(typename U::hasher*, typename U::reverse_iterator*); + template + static int test(typename U::hasher*, ...); + template + static char test(...); + + public: + static const bool value = sizeof(test(0, 0)) == sizeof(int); +}; + +template +const bool IsHashTable::value; + +template (0)) == sizeof(IsContainer)> struct IsRecursiveContainerImpl; template @@ -907,19 +942,34 @@ struct IsRecursiveContainerImpl : public false_type {}; template struct IsRecursiveContainerImpl { - typedef - typename IteratorTraits::value_type - value_type; + template + struct VoidT { + typedef void value_type; + }; + template + struct PathTraits { + typedef typename C1::const_iterator::value_type value_type; + }; + template + struct PathTraits< + C2, typename VoidT::value_type> { + typedef typename C2::iterator::value_type value_type; + }; + typedef typename IteratorTraits::value_type value_type; +#if GTEST_LANG_CXX11 + typedef std::is_same type; +#else typedef is_same type; +#endif }; // IsRecursiveContainer is a unary compile-time predicate that -// evaluates whether C is a recursive container type. A recursive container +// evaluates whether C is a recursive container type. A recursive container // type is a container type whose value_type is equal to the container type -// itself. An example for a recursive container type is -// boost::filesystem::path, whose iterator has a value_type that is equal to +// itself. An example for a recursive container type is +// boost::filesystem::path, whose iterator has a value_type that is equal to // boost::filesystem::path. -template +template struct IsRecursiveContainer : public IsRecursiveContainerImpl::type {}; // EnableIf::type is void when 'Cond' is true, and @@ -1218,4 +1268,3 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ - diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 74df5492..d22679f6 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -5185,8 +5185,8 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { // each TestCase and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see -// https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md . -// Returns the number of tests that should run. +// https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md +// . Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 11af9c9b..3791592b 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -64,6 +64,9 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { #include #include #include +#if GTEST_LANG_CXX11 +#include +#endif // GTEST_LANG_CXX11 #include "gtest/gtest-spi.h" #include "src/gtest-internal-inl.h" @@ -258,6 +261,8 @@ using testing::internal::IsContainer; using testing::internal::IsContainerTest; using testing::internal::IsNotContainer; using testing::internal::NativeArray; +using testing::internal::OsStackTraceGetter; +using testing::internal::OsStackTraceGetterInterface; using testing::internal::ParseInt32Flag; using testing::internal::RelationToSourceCopy; using testing::internal::RelationToSourceReference; @@ -274,6 +279,7 @@ using testing::internal::String; using testing::internal::TestEventListenersAccessor; using testing::internal::TestResultAccessor; using testing::internal::UInt32; +using testing::internal::UnitTestImpl; using testing::internal::WideStringToUtf8; using testing::internal::edit_distance::CalculateOptimalEdits; using testing::internal::edit_distance::CreateUnifiedDiff; @@ -7526,6 +7532,50 @@ TEST(IsContainerTestTest, WorksForContainer) { sizeof(IsContainerTest >(0))); } +#if GTEST_LANG_CXX11 +struct ConstOnlyContainerWithPointerIterator { + using const_iterator = int*; + const_iterator begin() const; + const_iterator end() const; +}; + +struct ConstOnlyContainerWithClassIterator { + struct const_iterator { + const int& operator*() const; + const_iterator& operator++(/* pre-increment */); + }; + const_iterator begin() const; + const_iterator end() const; +}; + +TEST(IsContainerTestTest, ConstOnlyContainer) { + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest(0))); + EXPECT_EQ(sizeof(IsContainer), + sizeof(IsContainerTest(0))); +} +#endif // GTEST_LANG_CXX11 + +// Tests IsHashTable. +struct AHashTable { + typedef void hasher; +}; +struct NotReallyAHashTable { + typedef void hasher; + typedef void reverse_iterator; +}; +TEST(IsHashTable, Basic) { + EXPECT_TRUE(testing::internal::IsHashTable::value); + EXPECT_FALSE(testing::internal::IsHashTable::value); +#if GTEST_LANG_CXX11 + EXPECT_FALSE(testing::internal::IsHashTable>::value); + EXPECT_TRUE(testing::internal::IsHashTable>::value); +#endif // GTEST_LANG_CXX11 +#if GTEST_HAS_HASH_SET_ + EXPECT_TRUE(testing::internal::IsHashTable>::value); +#endif // GTEST_HAS_HASH_SET_ +} + // Tests ArrayEq(). TEST(ArrayEqTest, WorksForDegeneratedArrays) { From 080fcbe0aae28dec00c2903ea04f2d2b022deb12 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 16 Mar 2018 13:36:36 -0400 Subject: [PATCH 2/3] cl 189032107 --- .../include/gmock/gmock-spec-builders.h | 1 - googlemock/test/gmock-matchers_test.cc | 1 - .../include/gtest/internal/gtest-internal.h | 26 +++++++------------ 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index f8e1c6ab..c1b63014 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -563,7 +563,6 @@ class ExpectationSet { public: // A bidirectional iterator that can read a const element in the set. typedef Expectation::Set::const_iterator const_iterator; - typedef Expectation::Set::iterator iterator; // An object stored in the set. This is an alias of Expectation. typedef Expectation::Set::value_type value_type; diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index f7bf2a82..829935ef 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -4526,7 +4526,6 @@ class Streamlike { class ConstIter; public: typedef ConstIter const_iterator; - typedef ConstIter iterator; typedef T value_type; template diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 612f8a4d..6e904a82 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -940,27 +940,19 @@ struct IsRecursiveContainerImpl; template struct IsRecursiveContainerImpl : public false_type {}; +// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to +// obey the same inconsistencies as the IsContainerTest, namely check if +// something is a container is relying on only const_iterator in C++11 and +// is relying on both const_iterator and iterator otherwise template struct IsRecursiveContainerImpl { - template - struct VoidT { - typedef void value_type; - }; - template - struct PathTraits { - typedef typename C1::const_iterator::value_type value_type; - }; - template - struct PathTraits< - C2, typename VoidT::value_type> { - typedef typename C2::iterator::value_type value_type; - }; - typedef typename IteratorTraits::value_type value_type; -#if GTEST_LANG_CXX11 - typedef std::is_same type; + #if GTEST_LANG_CXX11 + typedef typename IteratorTraits::value_type + value_type; #else - typedef is_same type; + typedef typename IteratorTraits::value_type value_type; #endif + typedef is_same type; }; // IsRecursiveContainer is a unary compile-time predicate that From a3c2e107aeb7e821b76164cea366094ce420b656 Mon Sep 17 00:00:00 2001 From: Gennadiy Civil Date: Fri, 16 Mar 2018 15:56:31 -0400 Subject: [PATCH 3/3] cl 189032107, again --- .../include/gtest/internal/gtest-internal.h | 23 +++++++++++++++---- googletest/test/gtest-printers_test.cc | 1 - 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 6e904a82..ffc22f92 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -933,19 +933,34 @@ struct IsHashTable { template const bool IsHashTable::value; +template +struct VoidT { + typedef void value_type; +}; + +template +struct HasValueType : false_type {}; +template +struct HasValueType > : true_type { +}; + template (0)) == sizeof(IsContainer)> + bool = sizeof(IsContainerTest(0)) == sizeof(IsContainer), + bool = HasValueType::value> struct IsRecursiveContainerImpl; -template -struct IsRecursiveContainerImpl : public false_type {}; +template +struct IsRecursiveContainerImpl : public false_type {}; // Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to // obey the same inconsistencies as the IsContainerTest, namely check if // something is a container is relying on only const_iterator in C++11 and // is relying on both const_iterator and iterator otherwise template -struct IsRecursiveContainerImpl { +struct IsRecursiveContainerImpl : public false_type {}; + +template +struct IsRecursiveContainerImpl { #if GTEST_LANG_CXX11 typedef typename IteratorTraits::value_type value_type; diff --git a/googletest/test/gtest-printers_test.cc b/googletest/test/gtest-printers_test.cc index ccac35b4..4487978c 100644 --- a/googletest/test/gtest-printers_test.cc +++ b/googletest/test/gtest-printers_test.cc @@ -195,7 +195,6 @@ class PathLike { struct iterator { typedef PathLike value_type; }; - typedef iterator const_iterator; PathLike() {}