Makes UnorderedElementsAre*() work with containers that don't have size() or empty().
This commit is contained in:
		@@ -3095,8 +3095,13 @@ class UnorderedElementsAreMatcherImpl
 | 
				
			|||||||
  virtual bool MatchAndExplain(Container container,
 | 
					  virtual bool MatchAndExplain(Container container,
 | 
				
			||||||
                               MatchResultListener* listener) const {
 | 
					                               MatchResultListener* listener) const {
 | 
				
			||||||
    StlContainerReference stl_container = View::ConstReference(container);
 | 
					    StlContainerReference stl_container = View::ConstReference(container);
 | 
				
			||||||
    size_t actual_count = stl_container.size();
 | 
					    ::std::vector<string> element_printouts;
 | 
				
			||||||
 | 
					    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 (actual_count == 0 && matchers_.empty()) {
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -3111,12 +3116,6 @@ class UnorderedElementsAreMatcherImpl
 | 
				
			|||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ::std::vector<string> element_printouts;
 | 
					 | 
				
			||||||
    MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
 | 
					 | 
				
			||||||
                                         stl_container.end(),
 | 
					 | 
				
			||||||
                                         &element_printouts,
 | 
					 | 
				
			||||||
                                         listener);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return VerifyAllElementsAndMatchersAreMatched(element_printouts,
 | 
					    return VerifyAllElementsAndMatchersAreMatched(element_printouts,
 | 
				
			||||||
                                                  matrix, listener) &&
 | 
					                                                  matrix, listener) &&
 | 
				
			||||||
           FindPairing(matrix, listener);
 | 
					           FindPairing(matrix, listener);
 | 
				
			||||||
@@ -3129,6 +3128,7 @@ class UnorderedElementsAreMatcherImpl
 | 
				
			|||||||
  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
 | 
					  MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
 | 
				
			||||||
                              ::std::vector<string>* element_printouts,
 | 
					                              ::std::vector<string>* element_printouts,
 | 
				
			||||||
                              MatchResultListener* listener) const {
 | 
					                              MatchResultListener* listener) const {
 | 
				
			||||||
 | 
					    element_printouts->clear();
 | 
				
			||||||
    ::std::vector<char> did_match;
 | 
					    ::std::vector<char> did_match;
 | 
				
			||||||
    size_t num_elements = 0;
 | 
					    size_t num_elements = 0;
 | 
				
			||||||
    for (; elem_first != elem_last; ++num_elements, ++elem_first) {
 | 
					    for (; elem_first != elem_last; ++num_elements, ++elem_first) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4430,7 +4430,7 @@ TEST(WhenSortedTest, WorksForStreamlike) {
 | 
				
			|||||||
  // Streamlike 'container' provides only minimal iterator support.
 | 
					  // Streamlike 'container' provides only minimal iterator support.
 | 
				
			||||||
  // Its iterators are tagged with input_iterator_tag.
 | 
					  // Its iterators are tagged with input_iterator_tag.
 | 
				
			||||||
  const int a[5] = { 2, 1, 4, 5, 3 };
 | 
					  const int a[5] = { 2, 1, 4, 5, 3 };
 | 
				
			||||||
  Streamlike<int> s(a, a + 5);
 | 
					  Streamlike<int> s(a, a + GMOCK_ARRAY_SIZE_(a));
 | 
				
			||||||
  EXPECT_THAT(s, WhenSorted(ElementsAre(1, 2, 3, 4, 5)));
 | 
					  EXPECT_THAT(s, WhenSorted(ElementsAre(1, 2, 3, 4, 5)));
 | 
				
			||||||
  EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3))));
 | 
					  EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3))));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -4465,6 +4465,25 @@ TEST(UnorderedElementsAreArrayTest, VectorBool) {
 | 
				
			|||||||
                                 actual, &listener)) << listener.str();
 | 
					                                 actual, &listener)) << listener.str();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(UnorderedElementsAreArrayTest, WorksForStreamlike) {
 | 
				
			||||||
 | 
					  // Streamlike 'container' provides only minimal iterator support.
 | 
				
			||||||
 | 
					  // Its iterators are tagged with input_iterator_tag, and it has no
 | 
				
			||||||
 | 
					  // size() or empty() methods.
 | 
				
			||||||
 | 
					  const int a[5] = { 2, 1, 4, 5, 3 };
 | 
				
			||||||
 | 
					  Streamlike<int> s(a, a + GMOCK_ARRAY_SIZE_(a));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ::std::vector<int> expected;
 | 
				
			||||||
 | 
					  expected.push_back(1);
 | 
				
			||||||
 | 
					  expected.push_back(2);
 | 
				
			||||||
 | 
					  expected.push_back(3);
 | 
				
			||||||
 | 
					  expected.push_back(4);
 | 
				
			||||||
 | 
					  expected.push_back(5);
 | 
				
			||||||
 | 
					  EXPECT_THAT(s, UnorderedElementsAreArray(expected));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  expected.push_back(6);
 | 
				
			||||||
 | 
					  EXPECT_THAT(s, Not(UnorderedElementsAreArray(expected)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UnorderedElementsAreTest : public testing::Test {
 | 
					class UnorderedElementsAreTest : public testing::Test {
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  typedef std::vector<int> IntVec;
 | 
					  typedef std::vector<int> IntVec;
 | 
				
			||||||
@@ -4493,6 +4512,17 @@ TEST_F(UnorderedElementsAreTest, FailsWhenAnElementMatchesNoMatcher) {
 | 
				
			|||||||
                                  s, &listener)) << listener.str();
 | 
					                                  s, &listener)) << listener.str();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_F(UnorderedElementsAreTest, WorksForStreamlike) {
 | 
				
			||||||
 | 
					  // Streamlike 'container' provides only minimal iterator support.
 | 
				
			||||||
 | 
					  // Its iterators are tagged with input_iterator_tag, and it has no
 | 
				
			||||||
 | 
					  // size() or empty() methods.
 | 
				
			||||||
 | 
					  const int a[5] = { 2, 1, 4, 5, 3 };
 | 
				
			||||||
 | 
					  Streamlike<int> s(a, a + GMOCK_ARRAY_SIZE_(a));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
 | 
				
			||||||
 | 
					  EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// One naive implementation of the matcher runs in O(N!) time, which is too
 | 
					// One naive implementation of the matcher runs in O(N!) time, which is too
 | 
				
			||||||
// slow for many real-world inputs. This test shows that our matcher can match
 | 
					// slow for many real-world inputs. This test shows that our matcher can match
 | 
				
			||||||
// 100 inputs very quickly (a few milliseconds).  An O(100!) is 10^158
 | 
					// 100 inputs very quickly (a few milliseconds).  An O(100!) is 10^158
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user