Push several shanges:
Make single argument constructors explicit in macros.
Remove NOMINMAX macro.
Add macros for disabling Microsoft Visual C++ warnings.
Add WhenDynamicCastTo<T> matcher.
A matcher that matches a pointer that matches inner_matcher when
dynamic_cast<T> is applied.
Add IWYU export pragmas to the tuple include lines.
Fix NativeArray to not require a copy constructor unless we ask for one.
This allows ElementsAre() to support non-copyable types.
Examine WINAPI_FAMILY_PARTITION macros to better distinguish windows platforms.
Author: martin@martin.st
From: https://codereview.appspot.com/57220043/
diff --git a/include/gmock/gmock-generated-actions.h b/include/gmock/gmock-generated-actions.h
index f511bc8..f8ffc50 100644
--- a/include/gmock/gmock-generated-actions.h
+++ b/include/gmock/gmock-generated-actions.h
@@ -1347,7 +1347,7 @@
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
class GMOCK_ACTION_CLASS_(name, value_params) {\
public:\
- GMOCK_ACTION_CLASS_(name, value_params)\
+ explicit GMOCK_ACTION_CLASS_(name, value_params)\
GMOCK_INTERNAL_INIT_##value_params {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
@@ -1455,7 +1455,7 @@
template <typename p0##_type>\
class name##ActionP {\
public:\
- name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
+ explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
diff --git a/include/gmock/gmock-generated-actions.h.pump b/include/gmock/gmock-generated-actions.h.pump
index 9fba598..9197e87 100644
--- a/include/gmock/gmock-generated-actions.h.pump
+++ b/include/gmock/gmock-generated-actions.h.pump
@@ -606,7 +606,7 @@
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
class GMOCK_ACTION_CLASS_(name, value_params) {\
public:\
- GMOCK_ACTION_CLASS_(name, value_params)\
+ explicit GMOCK_ACTION_CLASS_(name, value_params)\
GMOCK_INTERNAL_INIT_##value_params {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
@@ -694,7 +694,7 @@
#define $macro_name(name$for j [[, p$j]])\$template
class $class_name {\
public:\
- $class_name($ctor_param_list)$inits {}\
+ [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
diff --git a/include/gmock/gmock-generated-matchers.h b/include/gmock/gmock-generated-matchers.h
index 967fcf9..57056fd 100644
--- a/include/gmock/gmock-generated-matchers.h
+++ b/include/gmock/gmock-generated-matchers.h
@@ -1460,7 +1460,7 @@
return ::testing::Matcher<arg_type>(\
new gmock_Impl<arg_type>(p0));\
}\
- name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
+ explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
}\
p0##_type p0;\
private:\
diff --git a/include/gmock/gmock-generated-matchers.h.pump b/include/gmock/gmock-generated-matchers.h.pump
index 4b618a4..de30c2c 100644
--- a/include/gmock/gmock-generated-matchers.h.pump
+++ b/include/gmock/gmock-generated-matchers.h.pump
@@ -653,7 +653,7 @@
return ::testing::Matcher<arg_type>(\
new gmock_Impl<arg_type>($params));\
}\
- $class_name($ctor_param_list)$inits {\
+ [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\
}\$param_field_decls2
private:\
GTEST_DISALLOW_ASSIGN_($class_name);\
diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h
index 086cac3..bd90d81 100644
--- a/include/gmock/gmock-matchers.h
+++ b/include/gmock/gmock-matchers.h
@@ -1997,6 +1997,83 @@
GTEST_DISALLOW_ASSIGN_(PointeeMatcher);
};
+// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
+// reference that matches inner_matcher when dynamic_cast<T> is applied.
+// The result of dynamic_cast<To> is forwarded to the inner matcher.
+// If To is a pointer and the cast fails, the inner matcher will receive NULL.
+// If To is a reference and the cast fails, this matcher returns false
+// immediately.
+template <typename To>
+class WhenDynamicCastToMatcherBase {
+ public:
+ explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)
+ : matcher_(matcher) {}
+
+ void DescribeTo(::std::ostream* os) const {
+ GetCastTypeDescription(os);
+ matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ GetCastTypeDescription(os);
+ matcher_.DescribeNegationTo(os);
+ }
+
+ protected:
+ const Matcher<To> matcher_;
+
+ static string GetToName() {
+#if GTEST_HAS_RTTI
+ return GetTypeName<To>();
+#else // GTEST_HAS_RTTI
+ return "the target type";
+#endif // GTEST_HAS_RTTI
+ }
+
+ private:
+ static void GetCastTypeDescription(::std::ostream* os) {
+ *os << "when dynamic_cast to " << GetToName() << ", ";
+ }
+
+ GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
+};
+
+// Primary template.
+// To is a pointer. Cast and forward the result.
+template <typename To>
+class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {
+ public:
+ explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)
+ : WhenDynamicCastToMatcherBase<To>(matcher) {}
+
+ template <typename From>
+ bool MatchAndExplain(From from, MatchResultListener* listener) const {
+ // TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail?
+ To to = dynamic_cast<To>(from);
+ return MatchPrintAndExplain(to, this->matcher_, listener);
+ }
+};
+
+// Specialize for references.
+// In this case we return false if the dynamic_cast fails.
+template <typename To>
+class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
+ public:
+ explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)
+ : WhenDynamicCastToMatcherBase<To&>(matcher) {}
+
+ template <typename From>
+ bool MatchAndExplain(From& from, MatchResultListener* listener) const {
+ // We don't want an std::bad_cast here, so do the cast with pointers.
+ To* to = dynamic_cast<To*>(&from);
+ if (to == NULL) {
+ *listener << "which cannot be dynamic_cast to " << this->GetToName();
+ return false;
+ }
+ return MatchPrintAndExplain(*to, this->matcher_, listener);
+ }
+};
+
// Implements the Field() matcher for matching a field (i.e. member
// variable) of an object.
template <typename Class, typename FieldType>
@@ -3612,6 +3689,19 @@
return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
}
+// Creates a matcher that matches a pointer or reference that matches
+// inner_matcher when dynamic_cast<To> is applied.
+// The result of dynamic_cast<To> is forwarded to the inner matcher.
+// If To is a pointer and the cast fails, the inner matcher will receive NULL.
+// If To is a reference and the cast fails, this matcher returns false
+// immediately.
+template <typename To>
+inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> >
+WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
+ return MakePolymorphicMatcher(
+ internal::WhenDynamicCastToMatcher<To>(inner_matcher));
+}
+
// Creates a matcher that matches an object whose given field matches
// 'matcher'. For example,
// Field(&Foo::number, Ge(5))
@@ -4050,3 +4140,4 @@
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
+
diff --git a/include/gmock/internal/gmock-internal-utils.h b/include/gmock/internal/gmock-internal-utils.h
index 6110dd7..e2ddb05 100644
--- a/include/gmock/internal/gmock-internal-utils.h
+++ b/include/gmock/internal/gmock-internal-utils.h
@@ -447,16 +447,17 @@
// ConstReference(const char * (&)[4])')
// (and though the N parameter type is mismatched in the above explicit
// conversion of it doesn't help - only the conversion of the array).
- return type(const_cast<Element*>(&array[0]), N, kReference);
+ return type(const_cast<Element*>(&array[0]), N,
+ RelationToSourceReference());
#else
- return type(array, N, kReference);
+ return type(array, N, RelationToSourceReference());
#endif // GTEST_OS_SYMBIAN
}
static type Copy(const Element (&array)[N]) {
#if GTEST_OS_SYMBIAN
- return type(const_cast<Element*>(&array[0]), N, kCopy);
+ return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy());
#else
- return type(array, N, kCopy);
+ return type(array, N, RelationToSourceCopy());
#endif // GTEST_OS_SYMBIAN
}
};
@@ -473,10 +474,10 @@
static const_reference ConstReference(
const ::testing::tuple<ElementPointer, Size>& array) {
- return type(get<0>(array), get<1>(array), kReference);
+ return type(get<0>(array), get<1>(array), RelationToSourceReference());
}
static type Copy(const ::testing::tuple<ElementPointer, Size>& array) {
- return type(get<0>(array), get<1>(array), kCopy);
+ return type(get<0>(array), get<1>(array), RelationToSourceCopy());
}
};
@@ -507,3 +508,4 @@
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
+