(t reflect.Type, vx, vy reflect.Value)
| 508 | } |
| 509 | |
| 510 | func (s *state) compareMap(t reflect.Type, vx, vy reflect.Value) { |
| 511 | if vx.IsNil() || vy.IsNil() { |
| 512 | s.report(vx.IsNil() && vy.IsNil(), 0) |
| 513 | return |
| 514 | } |
| 515 | |
| 516 | // Cycle-detection for maps. |
| 517 | if eq, visited := s.curPtrs.Push(vx, vy); visited { |
| 518 | s.report(eq, reportByCycle) |
| 519 | return |
| 520 | } |
| 521 | defer s.curPtrs.Pop(vx, vy) |
| 522 | |
| 523 | // We combine and sort the two map keys so that we can perform the |
| 524 | // comparisons in a deterministic order. |
| 525 | step := MapIndex{&mapIndex{pathStep: pathStep{typ: t.Elem()}}} |
| 526 | for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) { |
| 527 | step.vx = vx.MapIndex(k) |
| 528 | step.vy = vy.MapIndex(k) |
| 529 | step.key = k |
| 530 | if !step.vx.IsValid() && !step.vy.IsValid() { |
| 531 | // It is possible for both vx and vy to be invalid if the |
| 532 | // key contained a NaN value in it. |
| 533 | // |
| 534 | // Even with the ability to retrieve NaN keys in Go 1.12, |
| 535 | // there still isn't a sensible way to compare the values since |
| 536 | // a NaN key may map to multiple unordered values. |
| 537 | // The most reasonable way to compare NaNs would be to compare the |
| 538 | // set of values. However, this is impossible to do efficiently |
| 539 | // since set equality is provably an O(n^2) operation given only |
| 540 | // an Equal function. If we had a Less function or Hash function, |
| 541 | // this could be done in O(n*log(n)) or O(n), respectively. |
| 542 | // |
| 543 | // Rather than adding complex logic to deal with NaNs, make it |
| 544 | // the user's responsibility to compare such obscure maps. |
| 545 | const help = "consider providing a Comparer to compare the map" |
| 546 | panic(fmt.Sprintf("%#v has map key with NaNs\n%s", s.curPath, help)) |
| 547 | } |
| 548 | s.compareAny(step) |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | func (s *state) comparePtr(t reflect.Type, vx, vy reflect.Value) { |
| 553 | if vx.IsNil() || vy.IsNil() { |
no test coverage detected