types/views: add LenIter method to slice view types

This is basically https://github.com/bradfitz/iter which was
a joke but now that Go's adding range over int soonish, might
as well. It simplies our code elsewher that uses slice views.

Updates #8948

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/8952/head
Brad Fitzpatrick 1 year ago committed by Brad Fitzpatrick
parent af2e4909b6
commit 261cc498d3

@ -73,6 +73,11 @@ func (v SliceView[T, V]) IsNil() bool { return v.ж == nil }
// Len returns the length of the slice. // Len returns the length of the slice.
func (v SliceView[T, V]) Len() int { return len(v.ж) } func (v SliceView[T, V]) Len() int { return len(v.ж) }
// LenIter returns a slice the same length as the v.Len().
// The caller can then range over it to get the valid indexes.
// It does not allocate.
func (v SliceView[T, V]) LenIter() []struct{} { return make([]struct{}, len(v.ж)) }
// At returns a View of the element at index `i` of the slice. // At returns a View of the element at index `i` of the slice.
func (v SliceView[T, V]) At(i int) V { return v.ж[i].View() } func (v SliceView[T, V]) At(i int) V { return v.ж[i].View() }
@ -129,6 +134,11 @@ func (v Slice[T]) IsNil() bool { return v.ж == nil }
// Len returns the length of the slice. // Len returns the length of the slice.
func (v Slice[T]) Len() int { return len(v.ж) } func (v Slice[T]) Len() int { return len(v.ж) }
// LenIter returns a slice the same length as the v.Len().
// The caller can then range over it to get the valid indexes.
// It does not allocate.
func (v Slice[T]) LenIter() []struct{} { return make([]struct{}, len(v.ж)) }
// At returns the element at index `i` of the slice. // At returns the element at index `i` of the slice.
func (v Slice[T]) At(i int) T { return v.ж[i] } func (v Slice[T]) At(i int) T { return v.ж[i] }
@ -233,6 +243,11 @@ func (v IPPrefixSlice) IsNil() bool { return v.ж.IsNil() }
// Len returns the length of the slice. // Len returns the length of the slice.
func (v IPPrefixSlice) Len() int { return v.ж.Len() } func (v IPPrefixSlice) Len() int { return v.ж.Len() }
// LenIter returns a slice the same length as the v.Len().
// The caller can then range over it to get the valid indexes.
// It does not allocate.
func (v IPPrefixSlice) LenIter() []struct{} { return make([]struct{}, v.ж.Len()) }
// At returns the IPPrefix at index `i` of the slice. // At returns the IPPrefix at index `i` of the slice.
func (v IPPrefixSlice) At(i int) netip.Prefix { return v.ж.At(i) } func (v IPPrefixSlice) At(i int) netip.Prefix { return v.ж.At(i) }

@ -138,3 +138,15 @@ func TestViewUtils(t *testing.T) {
SliceOf([]string{"b", "c"}).SliceTo(1)), SliceOf([]string{"b", "c"}).SliceTo(1)),
qt.Equals, true) qt.Equals, true)
} }
func TestLenIter(t *testing.T) {
orig := []string{"foo", "bar"}
var got []string
v := SliceOf(orig)
for i := range v.LenIter() {
got = append(got, v.At(i))
}
if !reflect.DeepEqual(orig, got) {
t.Errorf("got %q; want %q", got, orig)
}
}

Loading…
Cancel
Save