Introduce a BeginEndDistanceIs matcher for containers such as std::forward_list
which lack a size() member. Also pull in gtest 678.
This commit is contained in:
@@ -2267,6 +2267,67 @@ class SizeIsMatcher {
|
||||
GTEST_DISALLOW_ASSIGN_(SizeIsMatcher);
|
||||
};
|
||||
|
||||
// Implements a matcher that checks the begin()..end() distance of an STL-style
|
||||
// container.
|
||||
template <typename DistanceMatcher>
|
||||
class BeginEndDistanceIsMatcher {
|
||||
public:
|
||||
explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)
|
||||
: distance_matcher_(distance_matcher) {}
|
||||
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
return MakeMatcher(new Impl<Container>(distance_matcher_));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
class Impl : public MatcherInterface<Container> {
|
||||
public:
|
||||
typedef internal::StlContainerView<
|
||||
GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView;
|
||||
typedef typename std::iterator_traits<
|
||||
typename ContainerView::type::const_iterator>::difference_type
|
||||
DistanceType;
|
||||
explicit Impl(const DistanceMatcher& distance_matcher)
|
||||
: distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
|
||||
|
||||
virtual void DescribeTo(::std::ostream* os) const {
|
||||
*os << "distance between begin() and end() ";
|
||||
distance_matcher_.DescribeTo(os);
|
||||
}
|
||||
virtual void DescribeNegationTo(::std::ostream* os) const {
|
||||
*os << "distance between begin() and end() ";
|
||||
distance_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
virtual bool MatchAndExplain(Container container,
|
||||
MatchResultListener* listener) const {
|
||||
#if GTEST_LANG_CXX11
|
||||
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);
|
||||
*listener << "whose distance between begin() and end() " << distance
|
||||
<< (result ? " matches" : " doesn't match");
|
||||
PrintIfNotEmpty(distance_listener.str(), listener->stream());
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
const Matcher<DistanceType> distance_matcher_;
|
||||
GTEST_DISALLOW_ASSIGN_(Impl);
|
||||
};
|
||||
|
||||
private:
|
||||
const DistanceMatcher distance_matcher_;
|
||||
GTEST_DISALLOW_ASSIGN_(BeginEndDistanceIsMatcher);
|
||||
};
|
||||
|
||||
// Implements an equality matcher for any STL-style container whose elements
|
||||
// support ==. This matcher is like Eq(), but its failure explanations provide
|
||||
// more detailed information that is useful when the container is used as a set.
|
||||
@@ -3799,6 +3860,17 @@ SizeIs(const SizeMatcher& size_matcher) {
|
||||
return internal::SizeIsMatcher<SizeMatcher>(size_matcher);
|
||||
}
|
||||
|
||||
// Returns a matcher that matches the distance between the container's begin()
|
||||
// iterator and its end() iterator, i.e. the size of the container. This matcher
|
||||
// can be used instead of SizeIs with containers such as std::forward_list which
|
||||
// do not implement size(). The container must provide const_iterator (with
|
||||
// valid iterator_traits), begin() and end().
|
||||
template <typename DistanceMatcher>
|
||||
inline internal::BeginEndDistanceIsMatcher<DistanceMatcher>
|
||||
BeginEndDistanceIs(const DistanceMatcher& distance_matcher) {
|
||||
return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher);
|
||||
}
|
||||
|
||||
// Returns a matcher that matches an equal container.
|
||||
// This matcher behaves like Eq(), but in the event of mismatch lists the
|
||||
// values that are included in one container but not the other. (Duplicate
|
||||
|
||||
Reference in New Issue
Block a user