52 const char* matcher_name,
55 if (param_values.size() >= 1) result +=
" " +
JoinAsTuple(param_values);
56 return negation ?
"not (" + result +
")" : result;
131 ::std::vector<char> seen;
144 for (
size_t ilhs = 0; ilhs <
graph_->LhsSize(); ++ilhs) {
148 <<
"ilhs: " << ilhs <<
", left_[ilhs]: " <<
left_[ilhs];
150 seen.assign(
graph_->RhsSize(), 0);
153 ElementMatcherPairs result;
154 for (
size_t ilhs = 0; ilhs <
left_.size(); ++ilhs) {
155 size_t irhs =
left_[ilhs];
157 result.push_back(ElementMatcherPair(ilhs, irhs));
163 static const size_t kUnused =
static_cast<size_t>(-1);
182 for (
size_t irhs = 0; irhs <
graph_->RhsSize(); ++irhs) {
183 if ((*seen)[irhs])
continue;
184 if (!
graph_->HasEdge(ilhs, irhs))
continue;
230 ::std::ostream* stream) {
231 typedef ElementMatcherPairs::const_iterator Iter;
232 ::std::ostream& os = *stream;
234 const char* sep =
"";
235 for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
237 <<
"element #" << it->first <<
", "
238 <<
"matcher #" << it->second <<
")";
244 bool MatchMatrix::NextGraph() {
245 for (
size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
246 for (
size_t irhs = 0; irhs < RhsSize(); ++irhs) {
247 char& b = matched_[SpaceIndex(ilhs, irhs)];
258 void MatchMatrix::Randomize() {
259 for (
size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
260 for (
size_t irhs = 0; irhs < RhsSize(); ++irhs) {
261 char& b = matched_[SpaceIndex(ilhs, irhs)];
262 b =
static_cast<char>(rand() & 1);
267 std::string MatchMatrix::DebugString()
const {
268 ::std::stringstream ss;
269 const char* sep =
"";
270 for (
size_t i = 0;
i < LhsSize(); ++
i) {
272 for (
size_t j = 0; j < RhsSize(); ++j) {
280 void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
281 ::std::ostream* os)
const {
282 switch (match_flags()) {
283 case UnorderedMatcherRequire::ExactMatch:
284 if (matcher_describers_.empty()) {
288 if (matcher_describers_.size() == 1) {
289 *os <<
"has " << Elements(1) <<
" and that element ";
290 matcher_describers_[0]->DescribeTo(os);
293 *os <<
"has " << Elements(matcher_describers_.size())
294 <<
" and there exists some permutation of elements such that:\n";
296 case UnorderedMatcherRequire::Superset:
297 *os <<
"a surjection from elements to requirements exists such that:\n";
299 case UnorderedMatcherRequire::Subset:
300 *os <<
"an injection from elements to requirements exists such that:\n";
304 const char* sep =
"";
305 for (
size_t i = 0;
i != matcher_describers_.size(); ++
i) {
307 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
308 *os <<
" - element #" <<
i <<
" ";
310 *os <<
" - an element ";
312 matcher_describers_[
i]->DescribeTo(os);
313 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
321 void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
322 ::std::ostream* os)
const {
323 switch (match_flags()) {
324 case UnorderedMatcherRequire::ExactMatch:
325 if (matcher_describers_.empty()) {
326 *os <<
"isn't empty";
329 if (matcher_describers_.size() == 1) {
330 *os <<
"doesn't have " << Elements(1) <<
", or has " << Elements(1)
332 matcher_describers_[0]->DescribeNegationTo(os);
335 *os <<
"doesn't have " << Elements(matcher_describers_.size())
336 <<
", or there exists no permutation of elements such that:\n";
338 case UnorderedMatcherRequire::Superset:
339 *os <<
"no surjection from elements to requirements exists such that:\n";
341 case UnorderedMatcherRequire::Subset:
342 *os <<
"no injection from elements to requirements exists such that:\n";
345 const char* sep =
"";
346 for (
size_t i = 0;
i != matcher_describers_.size(); ++
i) {
348 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
349 *os <<
" - element #" <<
i <<
" ";
351 *os <<
" - an element ";
353 matcher_describers_[
i]->DescribeTo(os);
354 if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
367 bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
368 const ::std::vector<std::string>& element_printouts,
369 const MatchMatrix& matrix, MatchResultListener* listener)
const {
371 ::std::vector<char> element_matched(matrix.LhsSize(), 0);
372 ::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
374 for (
size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) {
375 for (
size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) {
376 char matched = matrix.HasEdge(ilhs, irhs);
377 element_matched[ilhs] |= matched;
378 matcher_matched[irhs] |= matched;
382 if (match_flags() & UnorderedMatcherRequire::Superset) {
384 "where the following matchers don't match any elements:\n";
385 for (
size_t mi = 0; mi < matcher_matched.size(); ++mi) {
386 if (matcher_matched[mi])
continue;
388 if (listener->IsInterested()) {
389 *listener << sep <<
"matcher #" << mi <<
": ";
390 matcher_describers_[mi]->DescribeTo(listener->stream());
396 if (match_flags() & UnorderedMatcherRequire::Subset) {
398 "where the following elements don't match any matchers:\n";
399 const char* outer_sep =
"";
401 outer_sep =
"\nand ";
403 for (
size_t ei = 0; ei < element_matched.size(); ++ei) {
404 if (element_matched[ei])
continue;
406 if (listener->IsInterested()) {
407 *listener << outer_sep << sep <<
"element #" << ei <<
": "
408 << element_printouts[ei];
417 bool UnorderedElementsAreMatcherImplBase::FindPairing(
418 const MatchMatrix& matrix, MatchResultListener* listener)
const {
421 size_t max_flow = matches.size();
422 if ((match_flags() & UnorderedMatcherRequire::Superset) &&
423 max_flow < matrix.RhsSize()) {
424 if (listener->IsInterested()) {
425 *listener <<
"where no permutation of the elements can satisfy all "
426 "matchers, and the closest match is "
427 << max_flow <<
" of " << matrix.RhsSize()
428 <<
" matchers with the pairings:\n";
433 if ((match_flags() & UnorderedMatcherRequire::Subset) &&
434 max_flow < matrix.LhsSize()) {
435 if (listener->IsInterested()) {
437 <<
"where not all elements can be matched, and the closest match is "
438 << max_flow <<
" of " << matrix.RhsSize()
439 <<
" matchers with the pairings:\n";
445 if (matches.size() > 1) {
446 if (listener->IsInterested()) {
447 const char* sep =
"where:\n";
448 for (
size_t mi = 0; mi < matches.size(); ++mi) {
449 *listener << sep <<
" - element #" << matches[mi].first
450 <<
" 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)
GTEST_API_ std::string JoinAsTuple(const Strings &fields)
::std::vector< size_t > left_
GTEST_API_ std::string FormatMatcherDescription(bool negation, const char *matcher_name, const Strings ¶m_values)
const MatchMatrix * graph_
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix &g)
::std::vector< size_t > right_