aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>2020-04-16 16:34:13 -0400
committerArthur O'Dwyer <arthur.j.odwyer@gmail.com>2020-04-16 19:12:52 -0400
commit4f002f1e236c1a0e7bdb096cd845f1a9c6c129c6 (patch)
tree7053684bafde3f8cf5f7e39e7d0961447f35bb44
parentdcc92d0ab6c4ce022162a23566d44f673251eee4 (diff)
downloadgoogletest-4f002f1e236c1a0e7bdb096cd845f1a9c6c129c6.tar.gz
googletest-4f002f1e236c1a0e7bdb096cd845f1a9c6c129c6.tar.bz2
googletest-4f002f1e236c1a0e7bdb096cd845f1a9c6c129c6.zip
VariadicMatcher needs a non-defaulted move constructor for compile-time performance.
We are about to remove all uses of GTEST_DISALLOW_ASSIGN_ in favor of using the Rule of Zero everywhere. Unfortunately, if we use the Rule of Zero here, then when the compiler needs to figure out if VariadicMatcher is move-constructible, it will recurse down into `tuple<Args...>`, which on libstdc++ recurses too deeply. In file included from googlemock/test/gmock-matchers_test.cc:43: In file included from googlemock/include/gmock/gmock-matchers.h:258: In file included from /usr/include/c++/5.5.0/algorithm:60: In file included from /usr/include/c++/5.5.0/utility:70: In file included from /usr/include/c++/5.5.0/bits/stl_pair.h:59: In file included from /usr/include/c++/5.5.0/bits/move.h:57: /usr/bin/include/c++/5.5.0/type_traits:115:26: fatal error: recursive template instantiation exceeded maximum depth of 256 : public conditional<_B1::value, _B1, _B2>::type ^ The move constructor is the only problematic case, for some unknown reason. With GTEST_DISALLOW_ASSIGN_, the presence of a copy assignment operator causes the move constructor to be non-declared, thus non-defaulted, thus non-problematic. Without GTEST_DISALLOW_ASSIGN_, we have to do one of the following: - Default the copy constructor, so that the move constructor will be non-declared. - Define our own non-defaulted move constructor. ...except that doing the latter STILL did not work! Fortunately, the former (default the copy constructor, don't provide any move constructor) both works in practice and is semantically equivalent to the old code.
-rw-r--r--googlemock/include/gmock/gmock-matchers.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index fe88a7c7..b5b662d4 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -1333,6 +1333,9 @@ class VariadicMatcher {
static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
}
+ VariadicMatcher(const VariadicMatcher&) = default;
+ VariadicMatcher& operator=(const VariadicMatcher&) = delete;
+
// This template type conversion operator allows an
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that
// all of the provided matchers (Matcher1, Matcher2, ...) can match.
@@ -1357,8 +1360,6 @@ class VariadicMatcher {
std::integral_constant<size_t, sizeof...(Args)>) const {}
std::tuple<Args...> matchers_;
-
- GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
};
template <typename... Args>