diff options
| author | Brad Fitzpatrick <bradfitz@tailscale.com> | 2023-08-18 08:03:32 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <brad@danga.com> | 2023-08-18 08:21:52 -0700 |
| commit | 261cc498d3ad1a09ecfd1baeef583dc260c85f38 (patch) | |
| tree | 2f7b45d1eadabf3d1bd586afaae00e4010db1c24 | |
| parent | af2e4909b6e977225922551f5b694f9d61c87545 (diff) | |
| download | tailscale-261cc498d3ad1a09ecfd1baeef583dc260c85f38.tar.xz tailscale-261cc498d3ad1a09ecfd1baeef583dc260c85f38.zip | |
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>
| -rw-r--r-- | types/views/views.go | 15 | ||||
| -rw-r--r-- | types/views/views_test.go | 12 |
2 files changed, 27 insertions, 0 deletions
diff --git a/types/views/views.go b/types/views/views.go index 5297ba864..b86c3f94a 100644 --- a/types/views/views.go +++ b/types/views/views.go @@ -73,6 +73,11 @@ func (v SliceView[T, V]) IsNil() bool { return v.ж == nil } // Len returns the length of the slice. 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. 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. 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. 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. 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. func (v IPPrefixSlice) At(i int) netip.Prefix { return v.ж.At(i) } diff --git a/types/views/views_test.go b/types/views/views_test.go index 536372bcd..c78bd6dde 100644 --- a/types/views/views_test.go +++ b/types/views/views_test.go @@ -138,3 +138,15 @@ func TestViewUtils(t *testing.T) { SliceOf([]string{"b", "c"}).SliceTo(1)), 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) + } +} |
