Skip to content

Commit

Permalink
slice: make Partition clip its output
Browse files Browse the repository at this point in the history
The result will still alias the input, but this ensures elements of the input
after the selected slice will not be modified by subsequent appends to the
result. This permits the caller to use the tail of the input slice more safely.
  • Loading branch information
creachadair committed Nov 28, 2024
1 parent 8b3f33c commit 6d570e4
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
7 changes: 5 additions & 2 deletions slice/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import (
// returned slice is:
//
// [6, 2, 8, 4]
//
// The capacity of the slice returned is clipped to its length, so that
// appending to it will not modify the elements of vs after those kept.
func Partition[T any](vs []T, keep func(T) bool) []T {
if len(vs) == 0 {
return vs
Expand All @@ -51,7 +54,7 @@ func Partition[T any](vs []T, keep func(T) bool) []T {
// If the right cursor reached the end, we're done: Everything left of i
// is kept, everything ≥ i is unkept.
if j == len(vs) {
return vs[:i]
return vs[:i:i]
}

// Reaching here, the elements under both cursors are out of
Expand All @@ -69,7 +72,7 @@ func Partition[T any](vs []T, keep func(T) bool) []T {
i++
j++
}
return vs[:i]
return vs[:i:i]
}

// Dedup rearranges the elements of vs in-place to deduplicate consecutive runs
Expand Down
8 changes: 8 additions & 0 deletions slice/slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,14 @@ func (tc *testCase[T]) partition(t *testing.T) {
if diff != "" {
t.Errorf("Partition result (-want, +got)\n%s", diff)
}

// Verify that the output is clipped to its length.
cp2 := copyOf(cp)
var zero T
_ = append(got, zero)
if diff := cmp.Diff(cp, cp2); diff != "" {
t.Errorf("After append to result (-got, +want):\n%s", diff)
}
}

func copyOf[T any](vs []T) []T {
Expand Down

0 comments on commit 6d570e4

Please sign in to comment.