gmock merging -2
This commit is contained in:
		@@ -514,7 +514,7 @@ template <typename T, typename M>
 | 
			
		||||
class MatcherCastImpl {
 | 
			
		||||
 public:
 | 
			
		||||
  static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
 | 
			
		||||
    // M can be a polymorhic matcher, in which case we want to use
 | 
			
		||||
    // M can be a polymorphic matcher, in which case we want to use
 | 
			
		||||
    // its conversion operator to create Matcher<T>.  Or it can be a value
 | 
			
		||||
    // that should be passed to the Matcher<T>'s constructor.
 | 
			
		||||
    //
 | 
			
		||||
@@ -3303,14 +3303,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
 | 
			
		||||
GTEST_API_ ElementMatcherPairs
 | 
			
		||||
FindMaxBipartiteMatching(const MatchMatrix& g);
 | 
			
		||||
 | 
			
		||||
GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
 | 
			
		||||
                            MatchResultListener* listener);
 | 
			
		||||
struct UnorderedMatcherRequire {
 | 
			
		||||
  enum Flags {
 | 
			
		||||
    Superset = 1 << 0,
 | 
			
		||||
    Subset = 1 << 1,
 | 
			
		||||
    ExactMatch = Superset | Subset,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Untyped base class for implementing UnorderedElementsAre.  By
 | 
			
		||||
// putting logic that's not specific to the element type here, we
 | 
			
		||||
// reduce binary bloat and increase compilation speed.
 | 
			
		||||
class GTEST_API_ UnorderedElementsAreMatcherImplBase {
 | 
			
		||||
 protected:
 | 
			
		||||
  explicit UnorderedElementsAreMatcherImplBase(
 | 
			
		||||
      UnorderedMatcherRequire::Flags matcher_flags)
 | 
			
		||||
      : match_flags_(matcher_flags) {}
 | 
			
		||||
 | 
			
		||||
  // A vector of matcher describers, one for each element matcher.
 | 
			
		||||
  // Does not own the describers (and thus can be used only when the
 | 
			
		||||
  // element matchers are alive).
 | 
			
		||||
@@ -3322,9 +3331,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
 | 
			
		||||
  // Describes the negation of this UnorderedElementsAre matcher.
 | 
			
		||||
  void DescribeNegationToImpl(::std::ostream* os) const;
 | 
			
		||||
 | 
			
		||||
  bool VerifyAllElementsAndMatchersAreMatched(
 | 
			
		||||
      const ::std::vector<std::string>& element_printouts,
 | 
			
		||||
      const MatchMatrix& matrix, MatchResultListener* listener) const;
 | 
			
		||||
  bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
 | 
			
		||||
                         const MatchMatrix& matrix,
 | 
			
		||||
                         MatchResultListener* listener) const;
 | 
			
		||||
 | 
			
		||||
  bool FindPairing(const MatchMatrix& matrix,
 | 
			
		||||
                   MatchResultListener* listener) const;
 | 
			
		||||
 | 
			
		||||
  MatcherDescriberVec& matcher_describers() {
 | 
			
		||||
    return matcher_describers_;
 | 
			
		||||
@@ -3334,13 +3346,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
 | 
			
		||||
    return Message() << n << " element" << (n == 1 ? "" : "s");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  UnorderedMatcherRequire::Flags match_flags_;
 | 
			
		||||
  MatcherDescriberVec matcher_describers_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implements unordered ElementsAre and unordered ElementsAreArray.
 | 
			
		||||
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
 | 
			
		||||
// IsSupersetOf.
 | 
			
		||||
template <typename Container>
 | 
			
		||||
class UnorderedElementsAreMatcherImpl
 | 
			
		||||
    : public MatcherInterface<Container>,
 | 
			
		||||
@@ -3353,10 +3369,10 @@ class UnorderedElementsAreMatcherImpl
 | 
			
		||||
  typedef typename StlContainer::const_iterator StlContainerConstIterator;
 | 
			
		||||
  typedef typename StlContainer::value_type Element;
 | 
			
		||||
 | 
			
		||||
  // Constructs the matcher from a sequence of element values or
 | 
			
		||||
  // element matchers.
 | 
			
		||||
  template <typename InputIter>
 | 
			
		||||
  UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) {
 | 
			
		||||
  UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
 | 
			
		||||
                                  InputIter first, InputIter last)
 | 
			
		||||
      : UnorderedElementsAreMatcherImplBase(matcher_flags) {
 | 
			
		||||
    for (; first != last; ++first) {
 | 
			
		||||
      matchers_.push_back(MatcherCast<const Element&>(*first));
 | 
			
		||||
      matcher_describers().push_back(matchers_.back().GetDescriber());
 | 
			
		||||
@@ -3377,34 +3393,32 @@ class UnorderedElementsAreMatcherImpl
 | 
			
		||||
                               MatchResultListener* listener) const {
 | 
			
		||||
    StlContainerReference stl_container = View::ConstReference(container);
 | 
			
		||||
    ::std::vector<std::string> element_printouts;
 | 
			
		||||
    MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
 | 
			
		||||
                                         stl_container.end(),
 | 
			
		||||
                                         &element_printouts,
 | 
			
		||||
                                         listener);
 | 
			
		||||
    MatchMatrix matrix =
 | 
			
		||||
        AnalyzeElements(stl_container.begin(), stl_container.end(),
 | 
			
		||||
                        &element_printouts, listener);
 | 
			
		||||
 | 
			
		||||
    const size_t actual_count = matrix.LhsSize();
 | 
			
		||||
    if (actual_count == 0 && matchers_.empty()) {
 | 
			
		||||
    if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (actual_count != matchers_.size()) {
 | 
			
		||||
      // The element count doesn't match.  If the container is empty,
 | 
			
		||||
      // there's no need to explain anything as Google Mock already
 | 
			
		||||
      // prints the empty container. Otherwise we just need to show
 | 
			
		||||
      // how many elements there actually are.
 | 
			
		||||
      if (actual_count != 0 && listener->IsInterested()) {
 | 
			
		||||
        *listener << "which has " << Elements(actual_count);
 | 
			
		||||
 | 
			
		||||
    if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
 | 
			
		||||
      if (matrix.LhsSize() != matrix.RhsSize()) {
 | 
			
		||||
        // The element count doesn't match.  If the container is empty,
 | 
			
		||||
        // there's no need to explain anything as Google Mock already
 | 
			
		||||
        // prints the empty container. Otherwise we just need to show
 | 
			
		||||
        // how many elements there actually are.
 | 
			
		||||
        if (matrix.LhsSize() != 0 && listener->IsInterested()) {
 | 
			
		||||
          *listener << "which has " << Elements(matrix.LhsSize());
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return VerifyAllElementsAndMatchersAreMatched(element_printouts,
 | 
			
		||||
                                                  matrix, listener) &&
 | 
			
		||||
    return VerifyMatchMatrix(element_printouts, matrix, listener) &&
 | 
			
		||||
           FindPairing(matrix, listener);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  typedef ::std::vector<Matcher<const Element&> > MatcherVec;
 | 
			
		||||
 | 
			
		||||
  template <typename ElementIter>
 | 
			
		||||
  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
 | 
			
		||||
                              ::std::vector<std::string>* element_printouts,
 | 
			
		||||
@@ -3431,7 +3445,7 @@ class UnorderedElementsAreMatcherImpl
 | 
			
		||||
    return matrix;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MatcherVec matchers_;
 | 
			
		||||
  ::std::vector<Matcher<const Element&> > matchers_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
 | 
			
		||||
};
 | 
			
		||||
@@ -3464,7 +3478,7 @@ class UnorderedElementsAreMatcher {
 | 
			
		||||
    TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
 | 
			
		||||
                         ::std::back_inserter(matchers));
 | 
			
		||||
    return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
 | 
			
		||||
                           matchers.begin(), matchers.end()));
 | 
			
		||||
        UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
@@ -3497,24 +3511,23 @@ class ElementsAreMatcher {
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Implements UnorderedElementsAreArray().
 | 
			
		||||
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
 | 
			
		||||
template <typename T>
 | 
			
		||||
class UnorderedElementsAreArrayMatcher {
 | 
			
		||||
 public:
 | 
			
		||||
  UnorderedElementsAreArrayMatcher() {}
 | 
			
		||||
 | 
			
		||||
  template <typename Iter>
 | 
			
		||||
  UnorderedElementsAreArrayMatcher(Iter first, Iter last)
 | 
			
		||||
      : matchers_(first, last) {}
 | 
			
		||||
  UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
 | 
			
		||||
                                   Iter first, Iter last)
 | 
			
		||||
      : match_flags_(match_flags), matchers_(first, last) {}
 | 
			
		||||
 | 
			
		||||
  template <typename Container>
 | 
			
		||||
  operator Matcher<Container>() const {
 | 
			
		||||
    return MakeMatcher(
 | 
			
		||||
        new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(),
 | 
			
		||||
                                                       matchers_.end()));
 | 
			
		||||
    return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
 | 
			
		||||
        match_flags_, matchers_.begin(), matchers_.end()));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  UnorderedMatcherRequire::Flags match_flags_;
 | 
			
		||||
  ::std::vector<T> matchers_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
 | 
			
		||||
@@ -3625,7 +3638,7 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
 | 
			
		||||
 | 
			
		||||
}  // namespace internal
 | 
			
		||||
 | 
			
		||||
// ElementsAreArray(first, last)
 | 
			
		||||
// ElementsAreArray(iterator_first, iterator_last)
 | 
			
		||||
// ElementsAreArray(pointer, count)
 | 
			
		||||
// ElementsAreArray(array)
 | 
			
		||||
// ElementsAreArray(container)
 | 
			
		||||
@@ -3674,20 +3687,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// UnorderedElementsAreArray(first, last)
 | 
			
		||||
// UnorderedElementsAreArray(iterator_first, iterator_last)
 | 
			
		||||
// UnorderedElementsAreArray(pointer, count)
 | 
			
		||||
// UnorderedElementsAreArray(array)
 | 
			
		||||
// UnorderedElementsAreArray(container)
 | 
			
		||||
// UnorderedElementsAreArray({ e1, e2, ..., en })
 | 
			
		||||
//
 | 
			
		||||
// The UnorderedElementsAreArray() functions are like
 | 
			
		||||
// ElementsAreArray(...), but allow matching the elements in any order.
 | 
			
		||||
// UnorderedElementsAreArray() verifies that a bijective mapping onto a
 | 
			
		||||
// collection of matchers exists.
 | 
			
		||||
//
 | 
			
		||||
// 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::UnorderedElementsAreArrayMatcher<
 | 
			
		||||
    typename ::std::iterator_traits<Iter>::value_type>
 | 
			
		||||
UnorderedElementsAreArray(Iter first, Iter last) {
 | 
			
		||||
  typedef typename ::std::iterator_traits<Iter>::value_type T;
 | 
			
		||||
  return internal::UnorderedElementsAreArrayMatcher<T>(first, last);
 | 
			
		||||
  return internal::UnorderedElementsAreArrayMatcher<T>(
 | 
			
		||||
      internal::UnorderedMatcherRequire::ExactMatch, first, last);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
@@ -3729,7 +3748,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
 | 
			
		||||
const internal::AnythingMatcher _ = {};
 | 
			
		||||
// Creates a matcher that matches any value of the given type T.
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); }
 | 
			
		||||
inline Matcher<T> A() {
 | 
			
		||||
  return Matcher<T>(new internal::AnyMatcherImpl<T>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Creates a matcher that matches any value of the given type T.
 | 
			
		||||
template <typename T>
 | 
			
		||||
@@ -4299,6 +4320,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
 | 
			
		||||
  return internal::ContainsMatcher<M>(matcher);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsSupersetOf(iterator_first, iterator_last)
 | 
			
		||||
// IsSupersetOf(pointer, count)
 | 
			
		||||
// IsSupersetOf(array)
 | 
			
		||||
// IsSupersetOf(container)
 | 
			
		||||
// IsSupersetOf({e1, e2, ..., en})
 | 
			
		||||
//
 | 
			
		||||
// IsSupersetOf() verifies that a surjective partial mapping onto a collection
 | 
			
		||||
// of matchers exists. In other words, a container matches
 | 
			
		||||
// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
 | 
			
		||||
// {y1, ..., yn} of some of the container's elements where y1 matches e1,
 | 
			
		||||
// ..., and yn matches en. Obviously, the size of the container must be >= n
 | 
			
		||||
// in order to have a match. Examples:
 | 
			
		||||
//
 | 
			
		||||
// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
 | 
			
		||||
//   1 matches Ne(0).
 | 
			
		||||
// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
 | 
			
		||||
//   both Eq(1) and Lt(2). The reason is that different matchers must be used
 | 
			
		||||
//   for elements in different slots of the container.
 | 
			
		||||
// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
 | 
			
		||||
//   Eq(1) and (the second) 1 matches Lt(2).
 | 
			
		||||
// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
 | 
			
		||||
//   Gt(1) and 3 matches (the second) Gt(1).
 | 
			
		||||
//
 | 
			
		||||
// 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::UnorderedElementsAreArrayMatcher<
 | 
			
		||||
    typename ::std::iterator_traits<Iter>::value_type>
 | 
			
		||||
IsSupersetOf(Iter first, Iter last) {
 | 
			
		||||
  typedef typename ::std::iterator_traits<Iter>::value_type T;
 | 
			
		||||
  return internal::UnorderedElementsAreArrayMatcher<T>(
 | 
			
		||||
      internal::UnorderedMatcherRequire::Superset, first, last);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
 | 
			
		||||
    const T* pointer, size_t count) {
 | 
			
		||||
  return IsSupersetOf(pointer, pointer + count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, size_t N>
 | 
			
		||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
 | 
			
		||||
    const T (&array)[N]) {
 | 
			
		||||
  return IsSupersetOf(array, N);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Container>
 | 
			
		||||
inline internal::UnorderedElementsAreArrayMatcher<
 | 
			
		||||
    typename Container::value_type>
 | 
			
		||||
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)
 | 
			
		||||
// IsSubsetOf(array)
 | 
			
		||||
// IsSubsetOf(container)
 | 
			
		||||
// IsSubsetOf({e1, e2, ..., en})
 | 
			
		||||
//
 | 
			
		||||
// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
 | 
			
		||||
// exists.  In other words, a container matches IsSubsetOf({e1, ..., en}) if and
 | 
			
		||||
// only if there is a subset of matchers {m1, ..., mk} which would match the
 | 
			
		||||
// container using UnorderedElementsAre.  Obviously, the size of the container
 | 
			
		||||
// must be <= n in order to have a match. Examples:
 | 
			
		||||
//
 | 
			
		||||
// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
 | 
			
		||||
// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
 | 
			
		||||
//   matches Lt(0).
 | 
			
		||||
// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
 | 
			
		||||
//   match Gt(0). The reason is that different matchers must be used for
 | 
			
		||||
//   elements in different slots of the container.
 | 
			
		||||
//
 | 
			
		||||
// 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::UnorderedElementsAreArrayMatcher<
 | 
			
		||||
    typename ::std::iterator_traits<Iter>::value_type>
 | 
			
		||||
IsSubsetOf(Iter first, Iter last) {
 | 
			
		||||
  typedef typename ::std::iterator_traits<Iter>::value_type T;
 | 
			
		||||
  return internal::UnorderedElementsAreArrayMatcher<T>(
 | 
			
		||||
      internal::UnorderedMatcherRequire::Subset, first, last);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
 | 
			
		||||
    const T* pointer, size_t count) {
 | 
			
		||||
  return IsSubsetOf(pointer, pointer + count);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T, size_t N>
 | 
			
		||||
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
 | 
			
		||||
    const T (&array)[N]) {
 | 
			
		||||
  return IsSubsetOf(array, N);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Container>
 | 
			
		||||
inline internal::UnorderedElementsAreArrayMatcher<
 | 
			
		||||
    typename Container::value_type>
 | 
			
		||||
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.
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user