MCPcopy
hub / github.com/google/go-cmp / compareSlice

Method compareSlice

cmp/compare.go:418–508  ·  view source on GitHub ↗
(t reflect.Type, vx, vy reflect.Value)

Source from the content-addressed store, hash-verified

416}
417
418func (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) {
419 isSlice := t.Kind() == reflect.Slice
420 if isSlice && (vx.IsNil() || vy.IsNil()) {
421 s.report(vx.IsNil() && vy.IsNil(), 0)
422 return
423 }
424
425 // NOTE: It is incorrect to call curPtrs.Push on the slice header pointer
426 // since slices represents a list of pointers, rather than a single pointer.
427 // The pointer checking logic must be handled on a per-element basis
428 // in compareAny.
429 //
430 // A slice header (see reflect.SliceHeader) in Go is a tuple of a starting
431 // pointer P, a length N, and a capacity C. Supposing each slice element has
432 // a memory size of M, then the slice is equivalent to the list of pointers:
433 // [P+i*M for i in range(N)]
434 //
435 // For example, v[:0] and v[:1] are slices with the same starting pointer,
436 // but they are clearly different values. Using the slice pointer alone
437 // violates the assumption that equal pointers implies equal values.
438
439 step := SliceIndex{&sliceIndex{pathStep: pathStep{typ: t.Elem()}, isSlice: isSlice}}
440 withIndexes := func(ix, iy int) SliceIndex {
441 if ix >= 0 {
442 step.vx, step.xkey = vx.Index(ix), ix
443 } else {
444 step.vx, step.xkey = reflect.Value{}, -1
445 }
446 if iy >= 0 {
447 step.vy, step.ykey = vy.Index(iy), iy
448 } else {
449 step.vy, step.ykey = reflect.Value{}, -1
450 }
451 return step
452 }
453
454 // Ignore options are able to ignore missing elements in a slice.
455 // However, detecting these reliably requires an optimal differencing
456 // algorithm, for which diff.Difference is not.
457 //
458 // Instead, we first iterate through both slices to detect which elements
459 // would be ignored if standing alone. The index of non-discarded elements
460 // are stored in a separate slice, which diffing is then performed on.
461 var indexesX, indexesY []int
462 var ignoredX, ignoredY []bool
463 for ix := 0; ix < vx.Len(); ix++ {
464 ignored := s.statelessCompare(withIndexes(ix, -1)).NumDiff == 0
465 if !ignored {
466 indexesX = append(indexesX, ix)
467 }
468 ignoredX = append(ignoredX, ignored)
469 }
470 for iy := 0; iy < vy.Len(); iy++ {
471 ignored := s.statelessCompare(withIndexes(-1, iy)).NumDiff == 0
472 if !ignored {
473 indexesY = append(indexesY, iy)
474 }
475 ignoredY = append(ignoredY, ignored)

Callers 1

compareAnyMethod · 0.95

Calls 7

reportMethod · 0.95
statelessCompareMethod · 0.95
compareAnyMethod · 0.95
DifferenceFunction · 0.92
IsNilMethod · 0.80
LenMethod · 0.65
IndexMethod · 0.45

Tested by

no test coverage detected