257257
258258#include < algorithm>
259259#include < cmath>
260+ #include < cstddef>
260261#include < exception>
261262#include < functional>
262263#include < initializer_list>
@@ -2097,11 +2098,11 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
20972098template <typename Class, typename FieldType>
20982099class FieldMatcher {
20992100 public:
2100- FieldMatcher (FieldType Class::*field,
2101+ FieldMatcher (FieldType Class::* field,
21012102 const Matcher<const FieldType&>& matcher)
21022103 : field_(field), matcher_(matcher), whose_field_(" whose given field " ) {}
21032104
2104- FieldMatcher (const std::string& field_name, FieldType Class::*field,
2105+ FieldMatcher (const std::string& field_name, FieldType Class::* field,
21052106 const Matcher<const FieldType&>& matcher)
21062107 : field_(field),
21072108 matcher_ (matcher),
@@ -2145,7 +2146,7 @@ class FieldMatcher {
21452146 return MatchAndExplainImpl (std::false_type (), *p, listener);
21462147 }
21472148
2148- const FieldType Class::*field_;
2149+ const FieldType Class::* field_;
21492150 const Matcher<const FieldType&> matcher_;
21502151
21512152 // Contains either "whose given field " if the name of the field is unknown
@@ -3291,8 +3292,8 @@ class PairMatcher {
32913292};
32923293
32933294template <typename T, size_t ... I>
3294- auto UnpackStructImpl (const T& t, std::index_sequence<I...>,
3295- int ) -> decltype(std::tie(get<I>(t)...)) {
3295+ auto UnpackStructImpl (const T& t, std::index_sequence<I...>, int )
3296+ -> decltype(std::tie(get<I>(t)...)) {
32963297 static_assert (std::tuple_size<T>::value == sizeof ...(I),
32973298 " Number of arguments doesn't match the number of fields." );
32983299 return std::tie (get<I>(t)...);
@@ -3581,7 +3582,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
35813582 StlContainerReference stl_container = View::ConstReference (container);
35823583 auto it = stl_container.begin ();
35833584 size_t exam_pos = 0 ;
3584- bool mismatch_found = false ; // Have we found a mismatched element yet?
3585+ bool unmatched_found = false ;
35853586
35863587 // Go through the elements and matchers in pairs, until we reach
35873588 // the end of either the elements or the matchers, or until we find a
@@ -3597,11 +3598,23 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
35973598 }
35983599
35993600 if (!match) {
3600- mismatch_found = true ;
3601+ unmatched_found = true ;
3602+ // We cannot store the iterator for the unmatched element to be used
3603+ // later, as some users use ElementsAre() with a "container" whose
3604+ // iterator is not copy-constructible or copy-assignable.
3605+ //
3606+ // We cannot store a pointer to the element either, as some container's
3607+ // iterators return a temporary.
3608+ //
3609+ // We cannot store the element itself either, as the element may not be
3610+ // copyable.
3611+ //
3612+ // Therefore, we just remember the index of the unmatched element,
3613+ // and use it later to print the unmatched element.
36013614 break ;
36023615 }
36033616 }
3604- // If mismatch_found is true, ' exam_pos' is the index of the mismatch.
3617+ // If unmatched_found is true, exam_pos is the index of the mismatch.
36053618
36063619 // Find how many elements the actual container has. We avoid
36073620 // calling size() s.t. this code works for stream-like "containers"
@@ -3622,10 +3635,27 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> {
36223635 return false ;
36233636 }
36243637
3625- if (mismatch_found ) {
3638+ if (unmatched_found ) {
36263639 // The element count matches, but the exam_pos-th element doesn't match.
36273640 if (listener_interested) {
3628- *listener << " whose element #" << exam_pos << " doesn't match" ;
3641+ // Find the unmatched element.
3642+ auto unmatched_it = stl_container.begin ();
3643+ // We cannot call std::advance() on the iterator, as some users use
3644+ // ElementsAre() with a "container" whose iterator is incompatible with
3645+ // std::advance() (e.g. it may not have the difference_type member
3646+ // type).
3647+ for (size_t i = 0 ; i != exam_pos; ++i) {
3648+ ++unmatched_it;
3649+ }
3650+
3651+ // If the array is long or the elements' print-out is large, it may be
3652+ // hard for the user to find the mismatched element and its
3653+ // corresponding matcher description. Therefore we print the index, the
3654+ // value of the mismatched element, and the corresponding matcher
3655+ // description to ease debugging.
3656+ *listener << " whose element #" << exam_pos << " ("
3657+ << PrintToString (*unmatched_it) << " ) " ;
3658+ matchers_[exam_pos].DescribeNegationTo (listener->stream ());
36293659 PrintIfNotEmpty (explanations[exam_pos], listener->stream ());
36303660 }
36313661 return false ;
@@ -4031,15 +4061,15 @@ GTEST_API_ std::string FormatMatcherDescription(
40314061// Overloads to support `OptionalMatcher` being used with a type that either
40324062// supports implicit conversion to bool or a `has_value()` method.
40334063template <typename Optional>
4034- auto IsOptionalEngaged (const Optional& optional,
4035- Rank1) -> decltype(!!optional) {
4064+ auto IsOptionalEngaged (const Optional& optional, Rank1)
4065+ -> decltype(!!optional) {
40364066 // The use of double-negation here is to preserve historical behavior where
40374067 // the matcher used `operator!` rather than directly using `operator bool`.
40384068 return !static_cast <bool >(!optional);
40394069}
40404070template <typename Optional>
4041- auto IsOptionalEngaged (const Optional& optional,
4042- Rank0) -> decltype(!optional.has_value()) {
4071+ auto IsOptionalEngaged (const Optional& optional, Rank0)
4072+ -> decltype(!optional.has_value()) {
40434073 return optional.has_value ();
40444074}
40454075
@@ -4567,7 +4597,7 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
45674597// matches a Foo object x if and only if x.number >= 5.
45684598template <typename Class, typename FieldType, typename FieldMatcher>
45694599inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field (
4570- FieldType Class::*field, const FieldMatcher& matcher) {
4600+ FieldType Class::* field, const FieldMatcher& matcher) {
45714601 return MakePolymorphicMatcher (internal::FieldMatcher<Class, FieldType>(
45724602 field, MatcherCast<const FieldType&>(matcher)));
45734603 // The call to MatcherCast() is required for supporting inner
@@ -4580,7 +4610,7 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
45804610// messages.
45814611template <typename Class, typename FieldType, typename FieldMatcher>
45824612inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field (
4583- const std::string& field_name, FieldType Class::*field,
4613+ const std::string& field_name, FieldType Class::* field,
45844614 const FieldMatcher& matcher) {
45854615 return MakePolymorphicMatcher (internal::FieldMatcher<Class, FieldType>(
45864616 field_name, field, MatcherCast<const FieldType&>(matcher)));
0 commit comments