diff options
Diffstat (limited to 'vendor/github.com/ugorji/go/codec/fastpath.go.tmpl')
| -rw-r--r-- | vendor/github.com/ugorji/go/codec/fastpath.go.tmpl | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/vendor/github.com/ugorji/go/codec/fastpath.go.tmpl b/vendor/github.com/ugorji/go/codec/fastpath.go.tmpl new file mode 100644 index 000000000..db60ea837 --- /dev/null +++ b/vendor/github.com/ugorji/go/codec/fastpath.go.tmpl @@ -0,0 +1,134 @@ +//go:build !notfastpath && !codec.notfastpath + +// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved. +// Use of this source code is governed by a MIT license found in the LICENSE file. + +// Code generated from fastpath.go.tmpl - DO NOT EDIT. + +package codec + +// Fast path functions try to create a fast path encode or decode implementation +// for common maps and slices. +// +// We define the functions and register them in this single file +// so as not to pollute the encode.go and decode.go, and create a dependency in there. +// This file can be omitted without causing a build failure. +// +// The advantage of fast paths is: +// - Many calls bypass reflection altogether +// +// Currently support +// - slice of all builtin types (numeric, bool, string, []byte) +// - maps of builtin types to builtin or interface{} type, EXCEPT FOR +// keys of type uintptr, int8/16/32, uint16/32, float32/64, bool, interface{} +// AND values of type type int8/16/32, uint16/32 +// This should provide adequate "typical" implementations. +// +// Note that fast track decode functions must handle values for which an address cannot be obtained. +// For example: +// m2 := map[string]int{} +// p2 := []interface{}{m2} +// // decoding into p2 will bomb if fast track functions do not treat like unaddressable. +// + +{{/* +// ---------------- +fastpathEncMap<KV>R func (mapped to type id), routes to: +- ft.EncMap<KV>V + +fastpathEncSlice<E>R func (mapped to type id), delegates to one of: +- ft.EncSlice<E>V +- ft.EncAsMapSlice<E>V (when mapbyslice ie f.ti.mbs=true) + +// ---------------- +fastpathDecSlice<E>R func (mapped to type id), delegates to: +- ft.DecSliceIntfY (when slice CAN be updated) +- ft.DecSliceIntfN (when slice CANNOT be updated e.g. from array or non-addressable slice) + +fastpathDecMap<KV>R func (mapped to type id), routes to +- ft.DecMap<KV>L (handles ptr which is changeable, and non-pointer which cannot be made if nil) + +// ---------------- +NOTE: +- fastpath typeswitch directly calls the secondary methods for builtin maps/slices with appropriate nil handling: + - except EncAsMapSlice<E>V which only applies to wrapper types not those in the switch +- fastpathEncXXX functions mapped to type ID MUST do nil-checks during encode + - they are only called by decodeValue/encodeValue or other code (same way kMap et al are called) +*/ -}} + +import ( + "reflect" + "sort" + "slices" +) + +const fastpathEnabled = true + +{{/* +const fastpathMapBySliceErrMsg = "mapBySlice requires even slice length, but got %v" +*/ -}} + +type fastpathARtid [{{ .FastpathLen }}]uintptr + +type fastpathRtRtid struct { + rtid uintptr + rt reflect.Type +} +type fastpathARtRtid [{{ .FastpathLen }}]fastpathRtRtid + +var ( + fastpathAvRtidArr fastpathARtid + fastpathAvRtRtidArr fastpathARtRtid + fastpathAvRtid = fastpathAvRtidArr[:] + fastpathAvRtRtid = fastpathAvRtRtidArr[:] +) + +func fastpathAvIndex(rtid uintptr) (i uint, ok bool) { + return searchRtids(fastpathAvRtid, rtid) +} + +func init() { + var i uint = 0 + fn := func(v interface{}) { + xrt := reflect.TypeOf(v) + xrtid := rt2id(xrt) + xptrtid := rt2id(reflect.PointerTo(xrt)) + {{- /* only the base slice/map rtid is put in fastpathAvIndex, since we only handle slices/map/array */}} + fastpathAvRtid[i] = xrtid + fastpathAvRtRtid[i] = fastpathRtRtid{ rtid: xrtid, rt: xrt } + {{- /* fastpath type switches however handle slices/map/array, and pointers to them */}} + encBuiltinRtids = append(encBuiltinRtids, xrtid, xptrtid) + decBuiltinRtids = append(decBuiltinRtids, xrtid, xptrtid) + i++ + } + {{/* do not register []byte in fastpath */}} + {{range .Values}}{{if not .Primitive}}{{if not .MapKey -}} + fn([]{{ .Elem }}(nil)) + {{end}}{{end}}{{end}} + + {{range .Values}}{{if not .Primitive}}{{if .MapKey -}} + fn(map[{{ .MapKey }}]{{ .Elem }}(nil)) + {{end}}{{end}}{{end}} + + sort.Slice(fastpathAvRtid, func(i, j int) bool { return fastpathAvRtid[i] < fastpathAvRtid[j] }) + sort.Slice(fastpathAvRtRtid, func(i, j int) bool { return fastpathAvRtRtid[i].rtid < fastpathAvRtRtid[j].rtid }) + slices.Sort(encBuiltinRtids) + slices.Sort(decBuiltinRtids) +} + +func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool { + switch v := iv.(type) { +{{range .Values}}{{if not .Primitive}}{{if not .MapKey -}} + case *[]{{ .Elem }}: + *v = nil +{{end}}{{end}}{{end}} +{{range .Values}}{{if not .Primitive}}{{if .MapKey -}} + case *map[{{ .MapKey }}]{{ .Elem }}: + *v = nil +{{end}}{{end}}{{end}} + default: + _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4 + return false + } + return true +} |
