53 bool negation,
const char* matcher_name,
54 const std::vector<const char*>& param_names,
const Strings& param_values) {
56 if (!param_values.empty()) {
59 return negation ?
"not (" + result +
")" : result;
134 ::std::vector<char> seen;
147 for (
size_t ilhs = 0; ilhs <
graph_->LhsSize(); ++ilhs) {
151 <<
"ilhs: " << ilhs <<
", left_[ilhs]: " <<
left_[ilhs];
153 seen.assign(
graph_->RhsSize(), 0);
156 ElementMatcherPairs result;
157 for (
size_t ilhs = 0; ilhs <
left_.size(); ++ilhs) {
158 size_t irhs =
left_[ilhs];
160 result.push_back(ElementMatcherPair(ilhs, irhs));
166 static const size_t kUnused =
static_cast<size_t>(-1);
185 for (
size_t irhs = 0; irhs <
graph_->RhsSize(); ++irhs) {
186 if ((*seen)[irhs])
continue;
187 if (!
graph_->HasEdge(ilhs, irhs))
continue;
233 ::std::ostream* stream) {
234 typedef ElementMatcherPairs::const_iterator Iter;
235 ::std::ostream& os = *stream;
237 const char* sep =
"";
238 for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
239 os << sep <<
"\n (" <<
"element #" << it->first <<
", " <<
"matcher #"
240 << it->second <<
")";
246 bool MatchMatrix::NextGraph() {
247 for (
size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
248 for (
size_t irhs = 0; irhs < RhsSize(); ++irhs) {
249 char& b = matched_[SpaceIndex(ilhs, irhs)];
260 void MatchMatrix::Randomize() {
261 for (
size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
262 for (
size_t irhs = 0; irhs < RhsSize(); ++irhs) {
263 char& b = matched_[SpaceIndex(ilhs, irhs)];
264 b =
static_cast<char>(rand() & 1);
269 std::string MatchMatrix::DebugString()
const {
270 ::std::stringstream ss;
271 const char* sep =
"";
272 for (
size_t i = 0;
i < LhsSize(); ++
i) {
274 for (
size_t j = 0; j < RhsSize(); ++j) {
282 void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
283 ::std::ostream* os)
const {
284 switch (match_flags()) {
285 case UnorderedMatcherRequire::ExactMatch:
286 if (matcher_describers_.empty()) {
290 if (matcher_describers_.size() == 1) {
291 *os <<
"has " << Elements(1) <<
" and that element ";
292 matcher_describers_[0]->DescribeTo(os);
295 *os <<
"has " << Elements(matcher_describers_.size())
296 <<
" and there exists some permutation of elements such that:\n";
298 case UnorderedMatcherRequire::Superset:
299 *os <<
"a surjection from elements to requirements exists such that:\n";
301 case UnorderedMatcherRequire::Subset:
302 *os <<
"an injection from elements to requirements exists such that:\n";
306 const char* sep =
"";
307 for (
size_t i = 0;
i != matcher_describers_.size(); ++
i) {
309 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
310 *os <<
" - element #" <<
i <<
" ";
312 *os <<
" - an element ";
314 matcher_describers_[
i]->DescribeTo(os);
315 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
323 void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
324 ::std::ostream* os)
const {
325 switch (match_flags()) {
326 case UnorderedMatcherRequire::ExactMatch:
327 if (matcher_describers_.empty()) {
328 *os <<
"isn't empty";
331 if (matcher_describers_.size() == 1) {
332 *os <<
"doesn't have " << Elements(1) <<
", or has " << Elements(1)
334 matcher_describers_[0]->DescribeNegationTo(os);
337 *os <<
"doesn't have " << Elements(matcher_describers_.size())
338 <<
", or there exists no permutation of elements such that:\n";
340 case UnorderedMatcherRequire::Superset:
341 *os <<
"no surjection from elements to requirements exists such that:\n";
343 case UnorderedMatcherRequire::Subset:
344 *os <<
"no injection from elements to requirements exists such that:\n";
347 const char* sep =
"";
348 for (
size_t i = 0;
i != matcher_describers_.size(); ++
i) {
350 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
351 *os <<
" - element #" <<
i <<
" ";
353 *os <<
" - an element ";
355 matcher_describers_[
i]->DescribeTo(os);
356 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
369 bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
370 const ::std::vector<std::string>& element_printouts,
371 const MatchMatrix& matrix, MatchResultListener* listener)
const {
372 if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
376 const bool is_exact_match_with_size_discrepency =
377 match_flags() == UnorderedMatcherRequire::ExactMatch &&
378 matrix.LhsSize() != matrix.RhsSize();
379 if (is_exact_match_with_size_discrepency) {
384 if (matrix.LhsSize() != 0 && listener->IsInterested()) {
385 *listener <<
"which has " << Elements(matrix.LhsSize()) <<
"\n";
389 bool result = !is_exact_match_with_size_discrepency;
390 ::std::vector<char> element_matched(matrix.LhsSize(), 0);
391 ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
393 for (
size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
394 for (
size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
395 char matched = matrix.HasEdge(ilhs, irhs);
396 element_matched[ilhs] |= matched;
397 matcher_matched[irhs] |= matched;
401 if (match_flags() & UnorderedMatcherRequire::Superset) {
403 "where the following matchers don't match any elements:\n";
404 for (
size_t mi = 0; mi < matcher_matched.size(); ++mi) {
405 if (matcher_matched[mi])
continue;
407 if (listener->IsInterested()) {
408 *listener << sep <<
"matcher #" << mi <<
": ";
409 matcher_describers_[mi]->DescribeTo(listener->stream());
415 if (match_flags() & UnorderedMatcherRequire::Subset) {
417 "where the following elements don't match any matchers:\n";
418 const char* outer_sep =
"";
420 outer_sep =
"\nand ";
422 for (
size_t ei = 0; ei < element_matched.size(); ++ei) {
423 if (element_matched[ei])
continue;
425 if (listener->IsInterested()) {
426 *listener << outer_sep << sep <<
"element #" << ei <<
": "
427 << element_printouts[ei];
436 bool UnorderedElementsAreMatcherImplBase::FindPairing(
437 const MatchMatrix& matrix, MatchResultListener* listener)
const {
440 size_t max_flow = matches.size();
441 if ((match_flags() & UnorderedMatcherRequire::Superset) &&
442 max_flow < matrix.RhsSize()) {
443 if (listener->IsInterested()) {
444 *listener <<
"where no permutation of the elements can satisfy all "
445 "matchers, and the closest match is "
446 << max_flow <<
" of " << matrix.RhsSize()
447 <<
" matchers with the pairings:\n";
452 if ((match_flags() & UnorderedMatcherRequire::Subset) &&
453 max_flow < matrix.LhsSize()) {
454 if (listener->IsInterested()) {
456 <<
"where not all elements can be matched, and the closest match is "
457 << max_flow <<
" of " << matrix.RhsSize()
458 <<
" matchers with the pairings:\n";
464 if (matches.size() > 1) {
465 if (listener->IsInterested()) {
466 const char* sep =
"where:\n";
467 for (
size_t mi = 0; mi < matches.size(); ++mi) {
468 *listener << sep <<
" - element #" << matches[mi].first
469 <<
" is matched by matcher #" << matches[mi].second;
::std::vector<::std::string > Strings
MaxBipartiteMatchState(const MatchMatrix &graph)
GTEST_API_ std::string ConvertIdentifierNameToWords(const char *id_name)
static const size_t kUnused
static void LogElementMatcherPairVec(const ElementMatcherPairs &pairs,::std::ostream *stream)
#define GTEST_CHECK_(condition)
ElementMatcherPairs Compute()
bool TryAugment(size_t ilhs,::std::vector< char > *seen)
::std::vector< size_t > left_
GTEST_API_ std::string FormatMatcherDescription(bool negation, const char *matcher_name, const std::vector< const char * > ¶m_names, const Strings ¶m_values)
const MatchMatrix * graph_
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix &g)
GTEST_API_ std::string JoinAsKeyValueTuple(const std::vector< const char * > &names, const Strings &values)
::std::vector< size_t > right_