diff options
Diffstat (limited to 'googlemock/include/gmock/gmock-matchers.h')
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 409 |
1 files changed, 225 insertions, 184 deletions
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 68278bea..b1c0dc04 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,13 +58,16 @@ #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 +// MSVC warning C5046 is new as of VS2017 version 15.8. +#if defined(_MSC_VER) && _MSC_VER >= 1915 +#define GMOCK_MAYBE_5046_ 5046 +#else +#define GMOCK_MAYBE_5046_ #endif GTEST_DISABLE_MSC_WARNINGS_PUSH_( - 4251 5046 /* class A needs to have dll-interface to be used by clients of - class B */ + 4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by + clients of class B */ /* Symbol involving type with internal linkage not defined */) namespace testing { @@ -128,19 +132,16 @@ class MatcherCastImpl { // polymorphic_matcher_or_value to Matcher<T> because it won't trigger // a user-defined conversion from M to T if one exists (assuming M is // a value). - return CastImpl( - polymorphic_matcher_or_value, - BooleanConstant< - internal::ImplicitlyConvertible<M, Matcher<T> >::value>(), - BooleanConstant< - internal::ImplicitlyConvertible<M, T>::value>()); + return CastImpl(polymorphic_matcher_or_value, + bool_constant<std::is_convertible<M, Matcher<T>>::value>(), + bool_constant<std::is_convertible<M, T>::value>()); } private: template <bool Ignore> static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, - BooleanConstant<true> /* convertible_to_matcher */, - BooleanConstant<Ignore>) { + bool_constant<true> /* convertible_to_matcher */, + bool_constant<Ignore>) { // M is implicitly convertible to Matcher<T>, which means that either // M is a polymorphic matcher or Matcher<T> has an implicit constructor // from M. In both cases using the implicit conversion will produce a @@ -155,9 +156,9 @@ class MatcherCastImpl { // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic // matcher. It's a value of a type implicitly convertible to T. Use direct // initialization to create a matcher. - static Matcher<T> CastImpl( - const M& value, BooleanConstant<false> /* convertible_to_matcher */, - BooleanConstant<true> /* convertible_to_T */) { + static Matcher<T> CastImpl(const M& value, + bool_constant<false> /* convertible_to_matcher */, + bool_constant<true> /* convertible_to_T */) { return Matcher<T>(ImplicitCast_<T>(value)); } @@ -171,9 +172,9 @@ class MatcherCastImpl { // (e.g. std::pair<const int, int> vs. std::pair<int, int>). // // We don't define this method inline as we need the declaration of Eq(). - static Matcher<T> CastImpl( - const M& value, BooleanConstant<false> /* convertible_to_matcher */, - BooleanConstant<false> /* convertible_to_T */); + static Matcher<T> CastImpl(const M& value, + bool_constant<false> /* convertible_to_matcher */, + bool_constant<false> /* convertible_to_T */); }; // This more specialized version is used when MatcherCast()'s argument @@ -194,7 +195,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 +208,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 +248,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: @@ -276,12 +272,12 @@ class SafeMatcherCastImpl { template <typename U> static inline Matcher<T> Cast(const Matcher<U>& matcher) { // Enforce that T can be implicitly converted to U. - GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value), - T_must_be_implicitly_convertible_to_U); + GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value), + "T must be implicitly convertible to U"); // Enforce that we are not converting a non-reference type T to a reference // type U. GTEST_COMPILE_ASSERT_( - internal::is_reference<T>::value || !internal::is_reference<U>::value, + std::is_reference<T>::value || !std::is_reference<U>::value, cannot_convert_non_reference_arg_to_reference); // In case both T and U are arithmetic types, enforce that the // conversion is not lossy. @@ -362,7 +358,7 @@ template <size_t N> class TuplePrefix { public: // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true - // iff the first N fields of matcher_tuple matches the first N + // if the first N fields of matcher_tuple matches the first N // fields of value_tuple, respectively. template <typename MatcherTuple, typename ValueTuple> static bool Matches(const MatcherTuple& matcher_tuple, @@ -387,11 +383,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: "; @@ -423,7 +417,7 @@ class TuplePrefix<0> { ::std::ostream* /* os */) {} }; -// TupleMatches(matcher_tuple, value_tuple) returns true iff all +// TupleMatches(matcher_tuple, value_tuple) returns true if all // matchers in matcher_tuple match the corresponding fields in // value_tuple. It is a compiler error if matcher_tuple and // value_tuple have different number of fields or incompatible field @@ -492,9 +486,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 +518,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 +534,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"; } @@ -679,7 +665,7 @@ class StrEqualityMatcher { MatchResultListener* listener) const { // This should fail to compile if absl::string_view is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } #endif // GTEST_HAS_ABSL @@ -749,7 +735,7 @@ class HasSubstrMatcher { MatchResultListener* listener) const { // This should fail to compile if absl::string_view is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } #endif // GTEST_HAS_ABSL @@ -806,7 +792,7 @@ class StartsWithMatcher { MatchResultListener* listener) const { // This should fail to compile if absl::string_view is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } #endif // GTEST_HAS_ABSL @@ -862,7 +848,7 @@ class EndsWithMatcher { MatchResultListener* listener) const { // This should fail to compile if absl::string_view is used with wide // strings. - const StringType& str = string(s); + const StringType& str = std::string(s); return MatchAndExplain(str, listener); } #endif // GTEST_HAS_ABSL @@ -918,7 +904,7 @@ class PairMatchBase { public: template <typename T1, typename T2> operator Matcher<::std::tuple<T1, T2>>() const { - return MakeMatcher(new Impl<::std::tuple<T1, T2>>); + return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>); } template <typename T1, typename T2> operator Matcher<const ::std::tuple<T1, T2>&>() const { @@ -976,12 +962,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 +1011,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 +1034,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 +1117,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 +1140,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; @@ -1195,6 +1179,37 @@ class AnyOfMatcherImpl template <typename... Args> using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>; +// Wrapper for implementation of Any/AllOfArray(). +template <template <class> class MatcherImpl, typename T> +class SomeOfArrayMatcher { + public: + // Constructs the matcher from a sequence of element values or + // element matchers. + template <typename Iter> + SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} + + template <typename U> + operator Matcher<U>() const { // NOLINT + using RawU = typename std::decay<U>::type; + std::vector<Matcher<RawU>> matchers; + for (const auto& matcher : matchers_) { + matchers.push_back(MatcherCast<RawU>(matcher)); + } + return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers))); + } + + private: + const ::std::vector<T> matchers_; + + GTEST_DISALLOW_ASSIGN_(SomeOfArrayMatcher); +}; + +template <typename T> +using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>; + +template <typename T> +using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>; + // Used for implementing Truly(pred), which turns a predicate into a // matcher. template <typename Predicate> @@ -1584,8 +1599,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: @@ -1593,8 +1607,9 @@ class PointeeMatcher { template <typename Pointer> class Impl : public MatcherInterface<Pointer> { public: - typedef typename PointeeOf<GTEST_REMOVE_CONST_( // NOLINT - GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee; + typedef + typename PointeeOf<typename std::remove_const<GTEST_REMOVE_REFERENCE_( + Pointer)>::type>::type Pointee; explicit Impl(const InnerMatcher& matcher) : matcher_(MatcherCast<const Pointee&>(matcher)) {} @@ -1676,7 +1691,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 +1744,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(), + typename std::is_pointer<typename std::remove_const<T>::type>::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 +1767,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 +1788,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 +1814,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(), + typename std::is_pointer<typename std::remove_const<T>::type>::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 +1829,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 +1837,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 +1858,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 +1898,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 +1955,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 +2005,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 +2030,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); @@ -2099,9 +2091,8 @@ class ContainerEqMatcher { template <typename LhsContainer> bool MatchAndExplain(const LhsContainer& lhs, MatchResultListener* listener) const { - // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug - // that causes LhsContainer to be a const type sometimes. - typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)> + typedef internal::StlContainerView< + typename std::remove_const<LhsContainer>::type> LhsView; typedef typename LhsView::type LhsStlContainer; StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); @@ -2269,7 +2260,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 +2463,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 +2481,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 +2495,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 +2513,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. @@ -2557,7 +2531,7 @@ class KeyMatcherImpl : public MatcherInterface<PairType> { testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { } - // Returns true iff 'key_value.first' (the key) matches the inner matcher. + // Returns true if 'key_value.first' (the key) matches the inner matcher. bool MatchAndExplain(PairType key_value, MatchResultListener* listener) const override { StringMatchResultListener inner_listener; @@ -2596,7 +2570,8 @@ class KeyMatcher { template <typename PairType> operator Matcher<PairType>() const { - return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_)); + return Matcher<PairType>( + new KeyMatcherImpl<const PairType&>(matcher_for_key_)); } private: @@ -2638,7 +2613,7 @@ class PairMatcherImpl : public MatcherInterface<PairType> { second_matcher_.DescribeNegationTo(os); } - // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second' + // Returns true if 'a_pair.first' matches first_matcher and 'a_pair.second' // matches second_matcher. bool MatchAndExplain(PairType a_pair, MatchResultListener* listener) const override { @@ -2701,9 +2676,8 @@ class PairMatcher { template <typename PairType> operator Matcher<PairType> () const { - return MakeMatcher( - new PairMatcherImpl<PairType>( - first_matcher_, second_matcher_)); + return Matcher<PairType>( + new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_)); } private: @@ -3086,8 +3060,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 +3092,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 +3112,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 +3137,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())); } @@ -3172,7 +3149,7 @@ class ElementsAreArrayMatcher { // Given a 2-tuple matcher tm of type Tuple2Matcher and a value second // of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm, -// second) is a polymorphic matcher that matches a value x iff tm +// second) is a polymorphic matcher that matches a value x if tm // matches tuple (x, second). Useful for implementing // UnorderedPointwise() in terms of UnorderedElementsAreArray(). // @@ -3237,7 +3214,7 @@ class BoundSecondMatcher { // Given a 2-tuple matcher tm and a value second, // MatcherBindSecond(tm, second) returns a matcher that matches a -// value x iff tm matches tuple (x, second). Useful for implementing +// value x if tm matches tuple (x, second). Useful for implementing // UnorderedPointwise() in terms of UnorderedElementsAreArray(). template <typename Tuple2Matcher, typename Second> BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( @@ -3263,7 +3240,7 @@ class OptionalMatcher { template <typename Optional> operator Matcher<Optional>() const { - return MakeMatcher(new Impl<Optional>(value_matcher_)); + return Matcher<Optional>(new Impl<const Optional&>(value_matcher_)); } template <typename Optional> @@ -3548,13 +3525,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 +3572,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. // @@ -3627,9 +3600,8 @@ inline Matcher<T> An() { return A<T>(); } template <typename T, typename M> Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( - const M& value, - internal::BooleanConstant<false> /* convertible_to_matcher */, - internal::BooleanConstant<false> /* convertible_to_T */) { + const M& value, internal::bool_constant<false> /* convertible_to_matcher */, + internal::bool_constant<false> /* convertible_to_T */) { return Eq(value); } @@ -3734,7 +3706,7 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) { // Creates a matcher that matches an object whose given field matches // 'matcher'. For example, // Field(&Foo::number, Ge(5)) -// matches a Foo object x iff x.number >= 5. +// matches a Foo object x if x.number >= 5. template <typename Class, typename FieldType, typename FieldMatcher> inline PolymorphicMatcher< internal::FieldMatcher<Class, FieldType> > Field( @@ -3761,7 +3733,7 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field( // Creates a matcher that matches an object whose given property // matches 'matcher'. For example, // Property(&Foo::str, StartsWith("hi")) -// matches a Foo object x iff x.str() starts with "hi". +// matches a Foo object x if x.str() starts with "hi". template <typename Class, typename PropertyType, typename PropertyMatcher> inline PolymorphicMatcher<internal::PropertyMatcher< Class, PropertyType, PropertyType (Class::*)() const> > @@ -3770,8 +3742,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 +3760,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 +3771,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,17 +3784,15 @@ 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 +// Creates a matcher that matches an object if the result of applying // a callable to x matches 'matcher'. // For example, // ResultOf(f, StartsWith("hi")) -// matches a Foo object x iff f(x) starts with "hi". +// matches a Foo object x if f(x) starts with "hi". // `callable` parameter can be a function, function pointer, or a functor. It is // required to keep no state affecting the results of the calls on it and make // no assumptions about how many calls will be made. Any state it keeps must be @@ -3889,7 +3855,7 @@ inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix)); } -#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING +#if GTEST_HAS_STD_WSTRING // Wide string matchers. // Matches a string equal to str. @@ -3942,7 +3908,7 @@ inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith( internal::EndsWithMatcher<std::wstring>(suffix)); } -#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING +#endif // GTEST_HAS_STD_WSTRING // Creates a polymorphic matcher that matches a 2-tuple where the // first field == the second field. @@ -4064,12 +4030,12 @@ BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { // values that are included in one container but not the other. (Duplicate // values and order differences are not explained.) template <typename Container> -inline PolymorphicMatcher<internal::ContainerEqMatcher< // NOLINT - GTEST_REMOVE_CONST_(Container)> > - ContainerEq(const Container& rhs) { +inline PolymorphicMatcher<internal::ContainerEqMatcher< + typename std::remove_const<Container>::type>> +ContainerEq(const Container& rhs) { // This following line is for working around a bug in MSVC 8.0, // which causes Container to be a const type sometimes. - typedef GTEST_REMOVE_CONST_(Container) RawContainer; + typedef typename std::remove_const<Container>::type RawContainer; return MakePolymorphicMatcher( internal::ContainerEqMatcher<RawContainer>(rhs)); } @@ -4102,17 +4068,16 @@ WhenSorted(const ContainerMatcher& container_matcher) { // LHS container and the RHS container respectively. template <typename TupleMatcher, typename Container> inline internal::PointwiseMatcher<TupleMatcher, - GTEST_REMOVE_CONST_(Container)> + typename std::remove_const<Container>::type> Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { // This following line is for working around a bug in MSVC 8.0, // which causes Container to be a const type sometimes (e.g. when // rhs is a const int[]).. - typedef GTEST_REMOVE_CONST_(Container) RawContainer; + typedef typename std::remove_const<Container>::type RawContainer; return internal::PointwiseMatcher<TupleMatcher, RawContainer>( tuple_matcher, rhs); } -#if GTEST_HAS_STD_INITIALIZER_LIST_ // Supports the Pointwise(m, {a, b, c}) syntax. template <typename TupleMatcher, typename T> @@ -4121,7 +4086,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 @@ -4137,14 +4101,15 @@ inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( template <typename Tuple2Matcher, typename RhsContainer> inline internal::UnorderedElementsAreArrayMatcher< typename internal::BoundSecondMatcher< - Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_( - RhsContainer)>::type::value_type> > + Tuple2Matcher, + typename internal::StlContainerView< + typename std::remove_const<RhsContainer>::type>::type::value_type>> UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, const RhsContainer& rhs_container) { // This following line is for working around a bug in MSVC 8.0, // which causes RhsContainer to be a const type sometimes (e.g. when // rhs_container is a const int[]). - typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer; + typedef typename std::remove_const<RhsContainer>::type RawRhsContainer; // RhsView allows the same code to handle RhsContainer being a // STL-style container and it being a native C-style array. @@ -4166,7 +4131,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 +4141,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 +4220,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 +4277,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. @@ -4383,7 +4342,7 @@ inline internal::MatcherAsPredicate<M> Matches(M matcher) { return internal::MatcherAsPredicate<M>(matcher); } -// Returns true iff the value matches the matcher. +// Returns true if the value matches the matcher. template <typename T, typename M> inline bool Value(const T& value, M matcher) { return testing::Matches(matcher)(value); @@ -4452,6 +4411,88 @@ internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf( matchers...); } +// AnyOfArray(array) +// AnyOfArray(pointer, count) +// AnyOfArray(container) +// AnyOfArray({ e1, e2, ..., en }) +// AnyOfArray(iterator_first, iterator_last) +// +// AnyOfArray() verifies whether a given value matches any member of a +// collection of matchers. +// +// AllOfArray(array) +// AllOfArray(pointer, count) +// AllOfArray(container) +// AllOfArray({ e1, e2, ..., en }) +// AllOfArray(iterator_first, iterator_last) +// +// AllOfArray() verifies whether a given value matches all members of a +// collection of matchers. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::AnyOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +AnyOfArray(Iter first, Iter last) { + return internal::AnyOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type>(first, last); +} + +template <typename Iter> +inline internal::AllOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +AllOfArray(Iter first, Iter last) { + return internal::AllOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type>(first, last); +} + +template <typename T> +inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) { + return AnyOfArray(ptr, ptr + count); +} + +template <typename T> +inline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) { + return AllOfArray(ptr, ptr + count); +} + +template <typename T, size_t N> +inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) { + return AnyOfArray(array, N); +} + +template <typename T, size_t N> +inline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) { + return AllOfArray(array, N); +} + +template <typename Container> +inline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray( + const Container& container) { + return AnyOfArray(container.begin(), container.end()); +} + +template <typename Container> +inline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray( + const Container& container) { + return AllOfArray(container.begin(), container.end()); +} + +template <typename T> +inline internal::AnyOfArrayMatcher<T> AnyOfArray( + ::std::initializer_list<T> xs) { + return AnyOfArray(xs.begin(), xs.end()); +} + +template <typename T> +inline internal::AllOfArrayMatcher<T> AllOfArray( + ::std::initializer_list<T> xs) { + return AllOfArray(xs.begin(), xs.end()); +} + // Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected // fields of it matches a_matcher. C++ doesn't support default // arguments for function templates, so we have to overload it. @@ -4507,7 +4548,7 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( // These macros allow using matchers to check values in Google Test // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) -// succeed iff the value matches the matcher. If the assertion fails, +// succeed if the value matches the matcher. If the assertion fails, // the value and the description of the matcher will be printed. #define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |