From a7e3cf08266d939e3b664c08ac97972ba53bde18 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Sat, 25 Feb 2023 17:45:29 -0800 Subject: [PATCH] reflect: add Slice3() --- src/reflect/value.go | 27 +++++++++++++++++++++++++++ src/reflect/value_test.go | 14 ++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/reflect/value.go b/src/reflect/value.go index 3216ada5..70a9ed28 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -431,6 +431,33 @@ func (v Value) Slice(i, j int) Value { } func (v Value) Slice3(i, j, k int) Value { + switch v.Kind() { + case Slice: + hdr := *(*sliceHeader)(v.value) + i, j, k := uintptr(i), uintptr(j), uintptr(k) + + if j < i || k < j || hdr.len < k { + slicePanic() + } + + elemSize := v.typecode.underlying().elem().Size() + + hdr.len = j - i + hdr.cap = k - i + hdr.data = unsafe.Add(hdr.data, i*elemSize) + + return Value{ + typecode: v.typecode, + value: unsafe.Pointer(&hdr), + flags: v.flags, + } + + case Array: + // TODO(dgryski): can't do this yet because the resulting value needs type v.elem(), not array of v.elem(). + // need to be able to look up this "new" type so pointer equality of types still works + + } + panic("unimplemented: (reflect.Value).Slice3()") } diff --git a/src/reflect/value_test.go b/src/reflect/value_test.go index d70984d9..d7fdcc30 100644 --- a/src/reflect/value_test.go +++ b/src/reflect/value_test.go @@ -147,6 +147,20 @@ func TestSlice(t *testing.T) { } } + s268 := s[2:6:8] + s268ref := refs.Slice3(2, 6, 8) + + if len(s268) != s268ref.Len() || cap(s268) != s268ref.Cap() { + t.Errorf("len(s268)=%d s268ref.Len()=%d cap(s268)=%d s268ref.Cap()=%d\n", len(s268), s268ref.Len(), cap(s268), s268ref.Cap()) + } + + for i, got := range s268 { + want := int(s268ref.Index(i).Int()) + if got != want { + t.Errorf("s268[%d]=%d, want %d", i, got, want) + } + } + refs = MakeSlice(TypeOf(s), 5, 10) s = refs.Interface().([]int)