reflect: add MakeSlice()
Этот коммит содержится в:
родитель
836689fdd2
коммит
5cc5f11b58
2 изменённых файлов: 40 добавлений и 1 удалений
|
@ -882,8 +882,40 @@ func (v Value) Convert(t Type) Value {
|
|||
panic("unimplemented: (reflect.Value).Convert()")
|
||||
}
|
||||
|
||||
//go:linkname slicePanic runtime.slicePanic
|
||||
func slicePanic()
|
||||
|
||||
func MakeSlice(typ Type, len, cap int) Value {
|
||||
panic("unimplemented: reflect.MakeSlice()")
|
||||
if typ.Kind() != Slice {
|
||||
panic("reflect.MakeSlice of non-slice type")
|
||||
}
|
||||
|
||||
rtype := typ.(*rawType)
|
||||
|
||||
ulen := uint(len)
|
||||
ucap := uint(cap)
|
||||
maxSize := (^uintptr(0)) / 2
|
||||
elementSize := rtype.elem().Size()
|
||||
if elementSize > 1 {
|
||||
maxSize /= uintptr(elementSize)
|
||||
}
|
||||
if ulen > ucap || ucap > uint(maxSize) {
|
||||
slicePanic()
|
||||
}
|
||||
|
||||
// This can't overflow because of the above checks.
|
||||
size := uintptr(ucap) * elementSize
|
||||
|
||||
var slice sliceHeader
|
||||
slice.cap = uintptr(ucap)
|
||||
slice.len = uintptr(ulen)
|
||||
slice.data = alloc(size, nil)
|
||||
|
||||
return Value{
|
||||
typecode: rtype,
|
||||
value: unsafe.Pointer(&slice),
|
||||
flags: valueFlagExported,
|
||||
}
|
||||
}
|
||||
|
||||
func Zero(typ Type) Value {
|
||||
|
|
|
@ -132,6 +132,13 @@ func TestSlice(t *testing.T) {
|
|||
t.Errorf("s[%d]=%d, want %d", i, s[i], i*10)
|
||||
}
|
||||
}
|
||||
|
||||
refs = MakeSlice(TypeOf(s), 5, 10)
|
||||
s = refs.Interface().([]int)
|
||||
|
||||
if len(s) != refs.Len() || cap(s) != refs.Cap() {
|
||||
t.Errorf("len(s)=%v refs.Len()=%v cap(s)=%v refs.Cap()=%v", len(s), refs.Len(), cap(s), refs.Cap())
|
||||
}
|
||||
}
|
||||
|
||||
func equal[T comparable](a, b []T) bool {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче