36 #include "gmock/gmock-matchers.h"
54 bool negation,
const char* matcher_name,
55 const std::vector<const char*>& param_names,
const Strings& param_values) {
57 if (param_values.size() >= 1) {
125 class MaxBipartiteMatchState {
135 ::std::vector<char>
seen;
152 <<
"ilhs: " << ilhs <<
", left_[ilhs]: " <<
left_[ilhs];
158 for (
size_t ilhs = 0; ilhs <
left_.size(); ++ilhs) {
159 size_t irhs =
left_[ilhs];
167 static const size_t kUnused =
static_cast<size_t>(-1);
187 if ((*
seen)[irhs])
continue;
223 ::std::vector<size_t>
left_;
224 ::std::vector<size_t>
right_;
230 return MaxBipartiteMatchState(g).Compute();
235 typedef ElementMatcherPairs::const_iterator
Iter;
236 ::std::ostream& os = *
stream;
238 const char*
sep =
"";
239 for (
Iter it = pairs.begin();
it != pairs.end(); ++
it) {
241 <<
"element #" <<
it->first <<
", "
242 <<
"matcher #" <<
it->second <<
")";
249 for (
size_t ilhs = 0; ilhs <
LhsSize(); ++ilhs) {
250 for (
size_t irhs = 0; irhs <
RhsSize(); ++irhs) {
263 for (
size_t ilhs = 0; ilhs <
LhsSize(); ++ilhs) {
264 for (
size_t irhs = 0; irhs <
RhsSize(); ++irhs) {
266 b =
static_cast<char>(rand() & 1);
272 ::std::stringstream ss;
273 const char*
sep =
"";
285 ::std::ostream* os)
const {
286 switch (match_flags()) {
287 case UnorderedMatcherRequire::ExactMatch:
293 *os <<
"has " <<
Elements(1) <<
" and that element ";
298 <<
" and there exists some permutation of elements such that:\n";
300 case UnorderedMatcherRequire::Superset:
301 *os <<
"a surjection from elements to requirements exists such that:\n";
303 case UnorderedMatcherRequire::Subset:
304 *os <<
"an injection from elements to requirements exists such that:\n";
308 const char*
sep =
"";
311 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
312 *os <<
" - element #" <<
i <<
" ";
314 *os <<
" - an element ";
317 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
326 ::std::ostream* os)
const {
327 switch (match_flags()) {
328 case UnorderedMatcherRequire::ExactMatch:
330 *os <<
"isn't empty";
340 <<
", or there exists no permutation of elements such that:\n";
342 case UnorderedMatcherRequire::Superset:
343 *os <<
"no surjection from elements to requirements exists such that:\n";
345 case UnorderedMatcherRequire::Subset:
346 *os <<
"no injection from elements to requirements exists such that:\n";
349 const char*
sep =
"";
352 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
353 *os <<
" - element #" <<
i <<
" ";
355 *os <<
" - an element ";
358 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
371 bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
372 const ::std::vector<std::string>& element_printouts,
373 const MatchMatrix& matrix, MatchResultListener* listener)
const {
375 ::std::vector<char> element_matched(matrix.LhsSize(), 0);
376 ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
378 for (
size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
379 for (
size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
380 char matched = matrix.HasEdge(ilhs, irhs);
381 element_matched[ilhs] |= matched;
382 matcher_matched[irhs] |= matched;
386 if (match_flags() & UnorderedMatcherRequire::Superset) {
388 "where the following matchers don't match any elements:\n";
389 for (
size_t mi = 0; mi < matcher_matched.size(); ++mi) {
390 if (matcher_matched[mi])
continue;
392 if (listener->IsInterested()) {
393 *listener <<
sep <<
"matcher #" << mi <<
": ";
400 if (match_flags() & UnorderedMatcherRequire::Subset) {
402 "where the following elements don't match any matchers:\n";
403 const char* outer_sep =
"";
405 outer_sep =
"\nand ";
407 for (
size_t ei = 0; ei < element_matched.size(); ++ei) {
408 if (element_matched[ei])
continue;
410 if (listener->IsInterested()) {
411 *listener << outer_sep <<
sep <<
"element #" << ei <<
": "
412 << element_printouts[ei];
422 const MatchMatrix& matrix, MatchResultListener* listener)
const {
425 size_t max_flow = matches.size();
426 if ((match_flags() & UnorderedMatcherRequire::Superset) &&
427 max_flow < matrix.RhsSize()) {
428 if (listener->IsInterested()) {
429 *listener <<
"where no permutation of the elements can satisfy all "
430 "matchers, and the closest match is "
431 << max_flow <<
" of " << matrix.RhsSize()
432 <<
" matchers with the pairings:\n";
437 if ((match_flags() & UnorderedMatcherRequire::Subset) &&
438 max_flow < matrix.LhsSize()) {
439 if (listener->IsInterested()) {
441 <<
"where not all elements can be matched, and the closest match is "
442 << max_flow <<
" of " << matrix.RhsSize()
443 <<
" matchers with the pairings:\n";
449 if (matches.size() > 1) {
450 if (listener->IsInterested()) {
451 const char*
sep =
"where:\n";
452 for (
size_t mi = 0; mi < matches.size(); ++mi) {
453 *listener <<
sep <<
" - element #" << matches[mi].first
454 <<
" is matched by matcher #" << matches[mi].second;