diff options
Diffstat (limited to 'googlemock/include/gmock/gmock-matchers.h')
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 180 |
1 files changed, 52 insertions, 128 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 68278bea..b99fdc36 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -44,6 +44,7 @@ #include <math.h> #include <algorithm> +#include <initializer_list> #include <iterator> #include <limits> #include <memory> @@ -57,10 +58,6 @@ #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" -#if GTEST_HAS_STD_INITIALIZER_LIST_ -# include <initializer_list> // NOLINT -- must be after gtest.h -#endif - GTEST_DISABLE_MSC_WARNINGS_PUSH_( 4251 5046 /* class A needs to have dll-interface to be used by clients of class B */ @@ -194,7 +191,6 @@ class MatcherCastImpl<T, Matcher<U> > { // We delegate the matching logic to the source matcher. bool MatchAndExplain(T x, MatchResultListener* listener) const override { -#if GTEST_LANG_CXX11 using FromType = typename std::remove_cv<typename std::remove_pointer< typename std::remove_reference<T>::type>::type>::type; using ToType = typename std::remove_cv<typename std::remove_pointer< @@ -208,7 +204,6 @@ class MatcherCastImpl<T, Matcher<U> > { std::is_same<FromType, ToType>::value || !std::is_base_of<FromType, ToType>::value, "Can't implicitly convert from <base> to <derived>"); -#endif // GTEST_LANG_CXX11 return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); } @@ -249,11 +244,8 @@ inline Matcher<T> MatcherCast(const M& matcher) { // Implements SafeMatcherCast(). // -// We use an intermediate class to do the actual safe casting as Nokia's -// Symbian compiler cannot decide between -// template <T, M> ... (M) and -// template <T, U> ... (const Matcher<U>&) -// for function templates but can for member function templates. +// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a +// workaround for a compiler bug, and can now be removed. template <typename T> class SafeMatcherCastImpl { public: @@ -387,11 +379,9 @@ class TuplePrefix { typename std::tuple_element<N - 1, MatcherTuple>::type matcher = std::get<N - 1>(matchers); typedef typename std::tuple_element<N - 1, ValueTuple>::type Value; - GTEST_REFERENCE_TO_CONST_(Value) value = std::get<N - 1>(values); + const Value& value = std::get<N - 1>(values); StringMatchResultListener listener; if (!matcher.MatchAndExplain(value, &listener)) { - // FIXME: include in the message the name of the parameter - // as used in MOCK_METHOD*() when possible. *os << " Expected arg #" << N - 1 << ": "; std::get<N - 1>(matchers).DescribeTo(os); *os << "\n Actual: "; @@ -492,9 +482,9 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { // Implements A<T>(). template <typename T> -class AnyMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { +class AnyMatcherImpl : public MatcherInterface<const T&> { public: - bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) /* x */, + bool MatchAndExplain(const T& /* x */, MatchResultListener* /* listener */) const override { return true; } @@ -524,11 +514,7 @@ class IsNullMatcher { template <typename Pointer> bool MatchAndExplain(const Pointer& p, MatchResultListener* /* listener */) const { -#if GTEST_LANG_CXX11 return p == nullptr; -#else // GTEST_LANG_CXX11 - return GetRawPointer(p) == NULL; -#endif // GTEST_LANG_CXX11 } void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } @@ -544,11 +530,7 @@ class NotNullMatcher { template <typename Pointer> bool MatchAndExplain(const Pointer& p, MatchResultListener* /* listener */) const { -#if GTEST_LANG_CXX11 return p != nullptr; -#else // GTEST_LANG_CXX11 - return GetRawPointer(p) != NULL; -#endif // GTEST_LANG_CXX11 } void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } @@ -976,12 +958,12 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { // will prevent different instantiations of NotMatcher from sharing // the same NotMatcherImpl<T> class. template <typename T> -class NotMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { +class NotMatcherImpl : public MatcherInterface<const T&> { public: explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {} - bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + bool MatchAndExplain(const T& x, MatchResultListener* listener) const override { return !matcher_.MatchAndExplain(x, listener); } @@ -1025,8 +1007,7 @@ class NotMatcher { // that will prevent different instantiations of BothOfMatcher from // sharing the same BothOfMatcherImpl<T> class. template <typename T> -class AllOfMatcherImpl - : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { +class AllOfMatcherImpl : public MatcherInterface<const T&> { public: explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) : matchers_(std::move(matchers)) {} @@ -1049,7 +1030,7 @@ class AllOfMatcherImpl *os << ")"; } - bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + bool MatchAndExplain(const T& x, MatchResultListener* listener) const override { // If either matcher1_ or matcher2_ doesn't match x, we only need // to explain why one of them fails. @@ -1132,8 +1113,7 @@ using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; // that will prevent different instantiations of AnyOfMatcher from // sharing the same EitherOfMatcherImpl<T> class. template <typename T> -class AnyOfMatcherImpl - : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> { +class AnyOfMatcherImpl : public MatcherInterface<const T&> { public: explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers) : matchers_(std::move(matchers)) {} @@ -1156,7 +1136,7 @@ class AnyOfMatcherImpl *os << ")"; } - bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, + bool MatchAndExplain(const T& x, MatchResultListener* listener) const override { std::string no_match_result; @@ -1584,8 +1564,7 @@ class PointeeMatcher { // enough for implementing the DescribeTo() method of Pointee(). template <typename Pointer> operator Matcher<Pointer>() const { - return Matcher<Pointer>( - new Impl<GTEST_REFERENCE_TO_CONST_(Pointer)>(matcher_)); + return Matcher<Pointer>(new Impl<const Pointer&>(matcher_)); } private: @@ -1676,7 +1655,6 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { template <typename From> bool MatchAndExplain(From from, MatchResultListener* listener) const { - // FIXME: Add more detail on failures. ie did the dyn_cast fail? To to = dynamic_cast<To>(from); return MatchPrintAndExplain(to, this->matcher_, listener); } @@ -1730,23 +1708,22 @@ class FieldMatcher { template <typename T> bool MatchAndExplain(const T& value, MatchResultListener* listener) const { + // FIXME: The dispatch on std::is_pointer was introduced as a workaround for + // a compiler bug, and can now be removed. return MatchAndExplainImpl( - typename ::testing::internal:: - is_pointer<GTEST_REMOVE_CONST_(T)>::type(), - value, listener); + typename std::is_pointer<GTEST_REMOVE_CONST_(T)>::type(), value, + listener); } private: - // The first argument of MatchAndExplainImpl() is needed to help - // Symbian's C++ compiler choose which overload to use. Its type is - // true_type iff the Field() matcher is used to match a pointer. - bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, + bool MatchAndExplainImpl(std::false_type /* is_not_pointer */, + const Class& obj, MatchResultListener* listener) const { *listener << whose_field_ << "is "; return MatchPrintAndExplain(obj.*field_, matcher_, listener); } - bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, + bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, MatchResultListener* listener) const { if (p == nullptr) return false; @@ -1754,7 +1731,7 @@ class FieldMatcher { // Since *p has a field, it must be a class/struct/union type and // thus cannot be a pointer. Therefore we pass false_type() as // the first argument. - return MatchAndExplainImpl(false_type(), *p, listener); + return MatchAndExplainImpl(std::false_type(), *p, listener); } const FieldType Class::*field_; @@ -1775,11 +1752,7 @@ class FieldMatcher { template <typename Class, typename PropertyType, typename Property> class PropertyMatcher { public: - // The property may have a reference type, so 'const PropertyType&' - // may cause double references and fail to compile. That's why we - // need GTEST_REFERENCE_TO_CONST, which works regardless of - // PropertyType being a reference or not. - typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; + typedef const PropertyType& RefToConstProperty; PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) : property_(property), @@ -1805,16 +1778,13 @@ class PropertyMatcher { template <typename T> bool MatchAndExplain(const T&value, MatchResultListener* listener) const { return MatchAndExplainImpl( - typename ::testing::internal:: - is_pointer<GTEST_REMOVE_CONST_(T)>::type(), - value, listener); + typename std::is_pointer<GTEST_REMOVE_CONST_(T)>::type(), value, + listener); } private: - // The first argument of MatchAndExplainImpl() is needed to help - // Symbian's C++ compiler choose which overload to use. Its type is - // true_type iff the Property() matcher is used to match a pointer. - bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, + bool MatchAndExplainImpl(std::false_type /* is_not_pointer */, + const Class& obj, MatchResultListener* listener) const { *listener << whose_property_ << "is "; // Cannot pass the return value (for example, int) to MatchPrintAndExplain, @@ -1823,7 +1793,7 @@ class PropertyMatcher { return MatchPrintAndExplain(result, matcher_, listener); } - bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p, + bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, MatchResultListener* listener) const { if (p == nullptr) return false; @@ -1831,7 +1801,7 @@ class PropertyMatcher { // Since *p has a property method, it must be a class/struct/union // type and thus cannot be a pointer. Therefore we pass // false_type() as the first argument. - return MatchAndExplainImpl(false_type(), *p, listener); + return MatchAndExplainImpl(std::false_type(), *p, listener); } Property property_; @@ -1852,14 +1822,8 @@ struct CallableTraits { static void CheckIsValid(Functor /* functor */) {} -#if GTEST_LANG_CXX11 template <typename T> static auto Invoke(Functor f, T arg) -> decltype(f(arg)) { return f(arg); } -#else - typedef typename Functor::result_type ResultType; - template <typename T> - static ResultType Invoke(Functor f, T arg) { return f(arg); } -#endif }; // Specialization for function pointers. @@ -1898,12 +1862,8 @@ class ResultOfMatcher { template <typename T> class Impl : public MatcherInterface<T> { -#if GTEST_LANG_CXX11 using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>( std::declval<CallableStorageType>(), std::declval<T>())); -#else - typedef typename CallableTraits<Callable>::ResultType ResultType; -#endif public: template <typename M> @@ -1959,7 +1919,7 @@ class SizeIsMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new Impl<Container>(size_matcher_)); + return Matcher<Container>(new Impl<const Container&>(size_matcher_)); } template <typename Container> @@ -2009,7 +1969,7 @@ class BeginEndDistanceIsMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new Impl<Container>(distance_matcher_)); + return Matcher<Container>(new Impl<const Container&>(distance_matcher_)); } template <typename Container> @@ -2034,13 +1994,9 @@ class BeginEndDistanceIsMatcher { bool MatchAndExplain(Container container, MatchResultListener* listener) const override { -#if GTEST_HAS_STD_BEGIN_AND_END_ using std::begin; using std::end; DistanceType distance = std::distance(begin(container), end(container)); -#else - DistanceType distance = std::distance(container.begin(), container.end()); -#endif StringMatchResultListener distance_listener; const bool result = distance_matcher_.MatchAndExplain(distance, &distance_listener); @@ -2269,7 +2225,8 @@ class PointwiseMatcher { !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value, use_UnorderedPointwise_with_hash_tables); - return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_)); + return Matcher<LhsContainer>( + new Impl<const LhsContainer&>(tuple_matcher_, rhs_)); } template <typename LhsContainer> @@ -2471,7 +2428,8 @@ class ContainsMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_)); + return Matcher<Container>( + new ContainsMatcherImpl<const Container&>(inner_matcher_)); } private: @@ -2488,7 +2446,8 @@ class EachMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_)); + return Matcher<Container>( + new EachMatcherImpl<const Container&>(inner_matcher_)); } private: @@ -2501,7 +2460,6 @@ struct Rank1 {}; struct Rank0 : Rank1 {}; namespace pair_getters { -#if GTEST_LANG_CXX11 using std::get; template <typename T> auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT @@ -2520,25 +2478,6 @@ template <typename T> auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT return x.second; } -#else -template <typename T> -typename T::first_type& First(T& x, Rank0) { // NOLINT - return x.first; -} -template <typename T> -const typename T::first_type& First(const T& x, Rank0) { - return x.first; -} - -template <typename T> -typename T::second_type& Second(T& x, Rank0) { // NOLINT - return x.second; -} -template <typename T> -const typename T::second_type& Second(const T& x, Rank0) { - return x.second; -} -#endif // GTEST_LANG_CXX11 } // namespace pair_getters // Implements Key(inner_matcher) for the given argument pair type. @@ -3086,8 +3025,10 @@ class UnorderedElementsAreMatcher { matchers.reserve(::std::tuple_size<MatcherTuple>::value); TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); - return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( - UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end())); + return Matcher<Container>( + new UnorderedElementsAreMatcherImpl<const Container&>( + UnorderedMatcherRequire::ExactMatch, matchers.begin(), + matchers.end())); } private: @@ -3116,8 +3057,8 @@ class ElementsAreMatcher { matchers.reserve(::std::tuple_size<MatcherTuple>::value); TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, ::std::back_inserter(matchers)); - return MakeMatcher(new ElementsAreMatcherImpl<Container>( - matchers.begin(), matchers.end())); + return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( + matchers.begin(), matchers.end())); } private: @@ -3136,8 +3077,9 @@ class UnorderedElementsAreArrayMatcher { template <typename Container> operator Matcher<Container>() const { - return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( - match_flags_, matchers_.begin(), matchers_.end())); + return Matcher<Container>( + new UnorderedElementsAreMatcherImpl<const Container&>( + match_flags_, matchers_.begin(), matchers_.end())); } private: @@ -3160,7 +3102,7 @@ class ElementsAreArrayMatcher { !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value, use_UnorderedElementsAreArray_with_hash_tables); - return MakeMatcher(new ElementsAreMatcherImpl<Container>( + return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( matchers_.begin(), matchers_.end())); } @@ -3548,13 +3490,11 @@ ElementsAreArray(const Container& container) { return ElementsAreArray(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> inline internal::ElementsAreArrayMatcher<T> ElementsAreArray(::std::initializer_list<T> xs) { return ElementsAreArray(xs.begin(), xs.end()); } -#endif // UnorderedElementsAreArray(iterator_first, iterator_last) // UnorderedElementsAreArray(pointer, count) @@ -3597,13 +3537,11 @@ UnorderedElementsAreArray(const Container& container) { return UnorderedElementsAreArray(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(::std::initializer_list<T> xs) { return UnorderedElementsAreArray(xs.begin(), xs.end()); } -#endif // _ is a matcher that matches anything of any type. // @@ -3770,8 +3708,7 @@ Property(PropertyType (Class::*property)() const, return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, PropertyType (Class::*)() const>( - property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + property, MatcherCast<const PropertyType&>(matcher))); // The call to MatcherCast() is required for supporting inner // matchers of compatible types. For example, it allows // Property(&Foo::bar, m) @@ -3789,11 +3726,9 @@ Property(const std::string& property_name, return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, PropertyType (Class::*)() const>( - property_name, property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + property_name, property, MatcherCast<const PropertyType&>(matcher))); } -#if GTEST_LANG_CXX11 // The same as above but for reference-qualified member functions. template <typename Class, typename PropertyType, typename PropertyMatcher> inline PolymorphicMatcher<internal::PropertyMatcher< @@ -3802,9 +3737,8 @@ Property(PropertyType (Class::*property)() const &, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, - PropertyType (Class::*)() const &>( - property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + PropertyType (Class::*)() const&>( + property, MatcherCast<const PropertyType&>(matcher))); } // Three-argument form for reference-qualified member functions. @@ -3816,11 +3750,9 @@ Property(const std::string& property_name, const PropertyMatcher& matcher) { return MakePolymorphicMatcher( internal::PropertyMatcher<Class, PropertyType, - PropertyType (Class::*)() const &>( - property_name, property, - MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); + PropertyType (Class::*)() const&>( + property_name, property, MatcherCast<const PropertyType&>(matcher))); } -#endif // Creates a matcher that matches an object iff the result of applying // a callable to x matches 'matcher'. @@ -4112,7 +4044,6 @@ Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { tuple_matcher, rhs); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ // Supports the Pointwise(m, {a, b, c}) syntax. template <typename TupleMatcher, typename T> @@ -4121,7 +4052,6 @@ inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( return Pointwise(tuple_matcher, std::vector<T>(rhs)); } -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ // UnorderedPointwise(pair_matcher, rhs) matches an STL-style // container or a native array that contains the same number of @@ -4166,7 +4096,6 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, return UnorderedElementsAreArray(matchers); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ // Supports the UnorderedPointwise(m, {a, b, c}) syntax. template <typename Tuple2Matcher, typename T> @@ -4177,7 +4106,6 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); } -#endif // GTEST_HAS_STD_INITIALIZER_LIST_ // Matches an STL-style container or a native array that contains at // least one element matching the given value or matcher. @@ -4257,13 +4185,11 @@ IsSupersetOf(const Container& container) { return IsSupersetOf(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( ::std::initializer_list<T> xs) { return IsSupersetOf(xs.begin(), xs.end()); } -#endif // IsSubsetOf(iterator_first, iterator_last) // IsSubsetOf(pointer, count) @@ -4316,13 +4242,11 @@ IsSubsetOf(const Container& container) { return IsSubsetOf(container.begin(), container.end()); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ template <typename T> inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( ::std::initializer_list<T> xs) { return IsSubsetOf(xs.begin(), xs.end()); } -#endif // Matches an STL-style container or a native array that contains only // elements matching the given value or matcher. |