pax_global_header00006660000000000000000000000064132454511240014513gustar00rootroot0000000000000052 comment=1df9eeb2bb81f327b96228865c5687bc2194af3f golang-github-modern-go-reflect2-1.0.0/000077500000000000000000000000001324545112400176315ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/.gitignore000066400000000000000000000000101324545112400216100ustar00rootroot00000000000000/vendor golang-github-modern-go-reflect2-1.0.0/Gopkg.lock000066400000000000000000000006661324545112400215620ustar00rootroot00000000000000# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. [[projects]] name = "github.com/modern-go/concurrent" packages = ["."] revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" version = "1.0.0" [solve-meta] analyzer-name = "dep" analyzer-version = 1 inputs-digest = "daee8a88b3498b61c5640056665b8b9eea062006f5e596bbb6a3ed9119a11ec7" solver-name = "gps-cdcl" solver-version = 1 golang-github-modern-go-reflect2-1.0.0/Gopkg.toml000066400000000000000000000015121324545112400215740ustar00rootroot00000000000000# Gopkg.toml example # # Refer to https://golang.github.io/dep/docs/Gopkg.toml.html # for detailed Gopkg.toml documentation. # # required = ["github.com/user/thing/cmd/thing"] # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] # # [[constraint]] # name = "github.com/user/project" # version = "1.0.0" # # [[constraint]] # name = "github.com/user/project2" # branch = "dev" # source = "github.com/myfork/project2" # # [[override]] # name = "github.com/x/y" # version = "2.4.0" # # [prune] # non-go = false # go-tests = true # unused-packages = true ignored = ["github.com/modern-go/test","github.com/modern-go/test/must","github.com/modern-go/test/should"] [[constraint]] name = "github.com/modern-go/concurrent" version = "1.0.0" [prune] go-tests = true unused-packages = true golang-github-modern-go-reflect2-1.0.0/LICENSE000066400000000000000000000261351324545112400206450ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. golang-github-modern-go-reflect2-1.0.0/README.md000066400000000000000000000000761324545112400211130ustar00rootroot00000000000000# reflect2 reflect api that avoids runtime reflect.Value cost golang-github-modern-go-reflect2-1.0.0/go_above_17.go000066400000000000000000000002531324545112400222500ustar00rootroot00000000000000//+build go1.7 package reflect2 import "unsafe" //go:linkname resolveTypeOff reflect.resolveTypeOff func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer golang-github-modern-go-reflect2-1.0.0/go_above_19.go000066400000000000000000000004011324545112400222450ustar00rootroot00000000000000//+build go1.9 package reflect2 import ( "unsafe" ) //go:linkname makemap reflect.makemap func makemap(rtype unsafe.Pointer, cap int) (m unsafe.Pointer) func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer { return makemap(rtype, cap) } golang-github-modern-go-reflect2-1.0.0/go_below_17.go000066400000000000000000000002071324545112400222630ustar00rootroot00000000000000//+build !go1.7 package reflect2 import "unsafe" func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer { return nil }golang-github-modern-go-reflect2-1.0.0/go_below_19.go000066400000000000000000000003641324545112400222710ustar00rootroot00000000000000//+build !go1.9 package reflect2 import ( "unsafe" ) //go:linkname makemap reflect.makemap func makemap(rtype unsafe.Pointer) (m unsafe.Pointer) func makeMapWithSize(rtype unsafe.Pointer, cap int) unsafe.Pointer { return makemap(rtype) } golang-github-modern-go-reflect2-1.0.0/reflect2.go000066400000000000000000000154361324545112400216770ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" "github.com/modern-go/concurrent" ) type Type interface { Kind() reflect.Kind // New return pointer to data of this type New() interface{} // UnsafeNew return the allocated space pointed by unsafe.Pointer UnsafeNew() unsafe.Pointer // PackEFace cast a unsafe pointer to object represented pointer PackEFace(ptr unsafe.Pointer) interface{} // Indirect dereference object represented pointer to this type Indirect(obj interface{}) interface{} // UnsafeIndirect dereference pointer to this type UnsafeIndirect(ptr unsafe.Pointer) interface{} // Type1 returns reflect.Type Type1() reflect.Type Implements(thatType Type) bool String() string RType() uintptr // interface{} of this type has pointer like behavior LikePtr() bool IsNullable() bool IsNil(obj interface{}) bool UnsafeIsNil(ptr unsafe.Pointer) bool Set(obj interface{}, val interface{}) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) AssignableTo(anotherType Type) bool } type ListType interface { Type Elem() Type SetIndex(obj interface{}, index int, elem interface{}) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) GetIndex(obj interface{}, index int) interface{} UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer } type ArrayType interface { ListType Len() int } type SliceType interface { ListType MakeSlice(length int, cap int) interface{} UnsafeMakeSlice(length int, cap int) unsafe.Pointer Grow(obj interface{}, newLength int) UnsafeGrow(ptr unsafe.Pointer, newLength int) Append(obj interface{}, elem interface{}) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) LengthOf(obj interface{}) int UnsafeLengthOf(ptr unsafe.Pointer) int SetNil(obj interface{}) UnsafeSetNil(ptr unsafe.Pointer) Cap(obj interface{}) int UnsafeCap(ptr unsafe.Pointer) int } type StructType interface { Type NumField() int Field(i int) StructField FieldByName(name string) StructField FieldByIndex(index []int) StructField FieldByNameFunc(match func(string) bool) StructField } type StructField interface { Offset() uintptr Name() string PkgPath() string Type() Type Tag() reflect.StructTag Index() []int Anonymous() bool Set(obj interface{}, value interface{}) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) Get(obj interface{}) interface{} UnsafeGet(obj unsafe.Pointer) unsafe.Pointer } type MapType interface { Type Key() Type Elem() Type MakeMap(cap int) interface{} UnsafeMakeMap(cap int) unsafe.Pointer SetIndex(obj interface{}, key interface{}, elem interface{}) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) GetIndex(obj interface{}, key interface{}) interface{} UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer Iterate(obj interface{}) MapIterator UnsafeIterate(obj unsafe.Pointer) MapIterator } type MapIterator interface { HasNext() bool Next() (key interface{}, elem interface{}) UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer) } type PtrType interface { Type Elem() Type } type InterfaceType interface { NumMethod() int } type Config struct { UseSafeImplementation bool } type API interface { TypeOf(obj interface{}) Type Type2(type1 reflect.Type) Type } var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze() var ConfigSafe = Config{UseSafeImplementation: true}.Froze() type frozenConfig struct { useSafeImplementation bool cache *concurrent.Map } func (cfg Config) Froze() *frozenConfig { return &frozenConfig{ useSafeImplementation: cfg.UseSafeImplementation, cache: concurrent.NewMap(), } } func (cfg *frozenConfig) TypeOf(obj interface{}) Type { cacheKey := uintptr(unpackEFace(obj).rtype) typeObj, found := cfg.cache.Load(cacheKey) if found { return typeObj.(Type) } return cfg.Type2(reflect.TypeOf(obj)) } func (cfg *frozenConfig) Type2(type1 reflect.Type) Type { cacheKey := uintptr(unpackEFace(type1).data) typeObj, found := cfg.cache.Load(cacheKey) if found { return typeObj.(Type) } type2 := cfg.wrapType(type1) cfg.cache.Store(cacheKey, type2) return type2 } func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type { safeType := safeType{Type: type1, cfg: cfg} switch type1.Kind() { case reflect.Struct: if cfg.useSafeImplementation { return &safeStructType{safeType} } return newUnsafeStructType(cfg, type1) case reflect.Array: if cfg.useSafeImplementation { return &safeSliceType{safeType} } return newUnsafeArrayType(cfg, type1) case reflect.Slice: if cfg.useSafeImplementation { return &safeSliceType{safeType} } return newUnsafeSliceType(cfg, type1) case reflect.Map: if cfg.useSafeImplementation { return &safeMapType{safeType} } return newUnsafeMapType(cfg, type1) case reflect.Ptr, reflect.Chan, reflect.Func: if cfg.useSafeImplementation { return &safeMapType{safeType} } return newUnsafePtrType(cfg, type1) case reflect.Interface: if cfg.useSafeImplementation { return &safeMapType{safeType} } if type1.NumMethod() == 0 { return newUnsafeEFaceType(cfg, type1) } return newUnsafeIFaceType(cfg, type1) default: if cfg.useSafeImplementation { return &safeType } return newUnsafeType(cfg, type1) } } func TypeOf(obj interface{}) Type { return ConfigUnsafe.TypeOf(obj) } func TypeOfPtr(obj interface{}) PtrType { return TypeOf(obj).(PtrType) } func Type2(type1 reflect.Type) Type { return ConfigUnsafe.Type2(type1) } func PtrTo(typ Type) Type { return Type2(reflect.PtrTo(typ.Type1())) } func PtrOf(obj interface{}) unsafe.Pointer { return unpackEFace(obj).data } func RTypeOf(obj interface{}) uintptr { return uintptr(unpackEFace(obj).rtype) } func IsNil(obj interface{}) bool { if obj == nil { return true } return unpackEFace(obj).data == nil } func IsNullable(kind reflect.Kind) bool { switch kind { case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface: return true } return false } func likePtrKind(kind reflect.Kind) bool { switch kind { case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func: return true } return false } func likePtrType(typ reflect.Type) bool { if likePtrKind(typ.Kind()) { return true } if typ.Kind() == reflect.Struct { if typ.NumField() != 1 { return false } return likePtrType(typ.Field(0).Type) } if typ.Kind() == reflect.Array { if typ.Len() != 1 { return false } return likePtrType(typ.Elem()) } return false } // NoEscape hides a pointer from escape analysis. noescape is // the identity function but escape analysis doesn't think the // output depends on the input. noescape is inlined and currently // compiles down to zero instructions. // USE CAREFULLY! //go:nosplit func NoEscape(p unsafe.Pointer) unsafe.Pointer { x := uintptr(p) return unsafe.Pointer(x ^ 0) }golang-github-modern-go-reflect2-1.0.0/reflect2_amd64.s000066400000000000000000000000001324545112400225040ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/reflect2_kind.go000066400000000000000000000014401324545112400226720ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) // DefaultTypeOfKind return the non aliased default type for the kind func DefaultTypeOfKind(kind reflect.Kind) Type { return kindTypes[kind] } var kindTypes = map[reflect.Kind]Type{ reflect.Bool: TypeOf(true), reflect.Uint8: TypeOf(uint8(0)), reflect.Int8: TypeOf(int8(0)), reflect.Uint16: TypeOf(uint16(0)), reflect.Int16: TypeOf(int16(0)), reflect.Uint32: TypeOf(uint32(0)), reflect.Int32: TypeOf(int32(0)), reflect.Uint64: TypeOf(uint64(0)), reflect.Int64: TypeOf(int64(0)), reflect.Uint: TypeOf(uint(0)), reflect.Int: TypeOf(int(0)), reflect.Float32: TypeOf(float32(0)), reflect.Float64: TypeOf(float64(0)), reflect.Uintptr: TypeOf(uintptr(0)), reflect.String: TypeOf(""), reflect.UnsafePointer: TypeOf(unsafe.Pointer(nil)), }golang-github-modern-go-reflect2-1.0.0/relfect2_386.s000066400000000000000000000000001324545112400221110ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_amd64p32.s000066400000000000000000000000001324545112400230310ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_arm.s000066400000000000000000000000001324545112400223500ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_arm64.s000066400000000000000000000000001324545112400225220ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_mips64x.s000066400000000000000000000000001324545112400231030ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_mipsx.s000066400000000000000000000000001324545112400227310ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_ppc64x.s000066400000000000000000000000001324545112400227150ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/relfect2_s390x.s000066400000000000000000000000001324545112400224570ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/safe_field.go000066400000000000000000000023501324545112400222410ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type safeField struct { reflect.StructField } func (field *safeField) Offset() uintptr { return field.StructField.Offset } func (field *safeField) Name() string { return field.StructField.Name } func (field *safeField) PkgPath() string { return field.StructField.PkgPath } func (field *safeField) Type() Type { panic("not implemented") } func (field *safeField) Tag() reflect.StructTag { return field.StructField.Tag } func (field *safeField) Index() []int { return field.StructField.Index } func (field *safeField) Anonymous() bool { return field.StructField.Anonymous } func (field *safeField) Set(obj interface{}, value interface{}) { val := reflect.ValueOf(obj).Elem() val.FieldByIndex(field.Index()).Set(reflect.ValueOf(value).Elem()) } func (field *safeField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { panic("unsafe operation is not supported") } func (field *safeField) Get(obj interface{}) interface{} { val := reflect.ValueOf(obj).Elem().FieldByIndex(field.Index()) ptr := reflect.New(val.Type()) ptr.Elem().Set(val) return ptr.Interface() } func (field *safeField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { panic("does not support unsafe operation") }golang-github-modern-go-reflect2-1.0.0/safe_map.go000066400000000000000000000050241324545112400217340ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type safeMapType struct { safeType } func (type2 *safeMapType) Key() Type { return type2.safeType.cfg.Type2(type2.Type.Key()) } func (type2 *safeMapType) MakeMap(cap int) interface{} { ptr := reflect.New(type2.Type) ptr.Elem().Set(reflect.MakeMap(type2.Type)) return ptr.Interface() } func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { panic("does not support unsafe operation") } func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { keyVal := reflect.ValueOf(key) elemVal := reflect.ValueOf(elem) val := reflect.ValueOf(obj) val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem()) } func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { panic("does not support unsafe operation") } func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { keyVal := reflect.ValueOf(key) if key == nil { keyVal = reflect.New(type2.Type.Key()).Elem() } val := reflect.ValueOf(obj).MapIndex(keyVal) if !val.IsValid() { return nil, false } return val.Interface(), true } func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} { val := reflect.ValueOf(obj).Elem() keyVal := reflect.ValueOf(key).Elem() elemVal := val.MapIndex(keyVal) if !elemVal.IsValid() { ptr := reflect.New(reflect.PtrTo(val.Type().Elem())) return ptr.Elem().Interface() } ptr := reflect.New(elemVal.Type()) ptr.Elem().Set(elemVal) return ptr.Interface() } func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { panic("does not support unsafe operation") } func (type2 *safeMapType) Iterate(obj interface{}) MapIterator { m := reflect.ValueOf(obj).Elem() return &safeMapIterator{ m: m, keys: m.MapKeys(), } } func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { panic("does not support unsafe operation") } type safeMapIterator struct { i int m reflect.Value keys []reflect.Value } func (iter *safeMapIterator) HasNext() bool { return iter.i != len(iter.keys) } func (iter *safeMapIterator) Next() (interface{}, interface{}) { key := iter.keys[iter.i] elem := iter.m.MapIndex(key) iter.i += 1 keyPtr := reflect.New(key.Type()) keyPtr.Elem().Set(key) elemPtr := reflect.New(elem.Type()) elemPtr.Elem().Set(elem) return keyPtr.Interface(), elemPtr.Interface() } func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { panic("does not support unsafe operation") }golang-github-modern-go-reflect2-1.0.0/safe_slice.go000066400000000000000000000047531324545112400222660ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type safeSliceType struct { safeType } func (type2 *safeSliceType) SetIndex(obj interface{}, index int, value interface{}) { val := reflect.ValueOf(obj).Elem() elem := reflect.ValueOf(value).Elem() val.Index(index).Set(elem) } func (type2 *safeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, value unsafe.Pointer) { panic("does not support unsafe operation") } func (type2 *safeSliceType) GetIndex(obj interface{}, index int) interface{} { val := reflect.ValueOf(obj).Elem() elem := val.Index(index) ptr := reflect.New(elem.Type()) ptr.Elem().Set(elem) return ptr.Interface() } func (type2 *safeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { panic("does not support unsafe operation") } func (type2 *safeSliceType) MakeSlice(length int, cap int) interface{} { val := reflect.MakeSlice(type2.Type, length, cap) ptr := reflect.New(val.Type()) ptr.Elem().Set(val) return ptr.Interface() } func (type2 *safeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { panic("does not support unsafe operation") } func (type2 *safeSliceType) Grow(obj interface{}, newLength int) { oldCap := type2.Cap(obj) oldSlice := reflect.ValueOf(obj).Elem() delta := newLength - oldCap deltaVals := make([]reflect.Value, delta) newSlice := reflect.Append(oldSlice, deltaVals...) oldSlice.Set(newSlice) } func (type2 *safeSliceType) UnsafeGrow(ptr unsafe.Pointer, newLength int) { panic("does not support unsafe operation") } func (type2 *safeSliceType) Append(obj interface{}, elem interface{}) { val := reflect.ValueOf(obj).Elem() elemVal := reflect.ValueOf(elem).Elem() newVal := reflect.Append(val, elemVal) val.Set(newVal) } func (type2 *safeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { panic("does not support unsafe operation") } func (type2 *safeSliceType) SetNil(obj interface{}) { val := reflect.ValueOf(obj).Elem() val.Set(reflect.Zero(val.Type())) } func (type2 *safeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { panic("does not support unsafe operation") } func (type2 *safeSliceType) LengthOf(obj interface{}) int { return reflect.ValueOf(obj).Elem().Len() } func (type2 *safeSliceType) UnsafeLengthOf(ptr unsafe.Pointer) int { panic("does not support unsafe operation") } func (type2 *safeSliceType) Cap(obj interface{}) int { return reflect.ValueOf(obj).Elem().Cap() } func (type2 *safeSliceType) UnsafeCap(ptr unsafe.Pointer) int { panic("does not support unsafe operation") }golang-github-modern-go-reflect2-1.0.0/safe_struct.go000066400000000000000000000004161324545112400225030ustar00rootroot00000000000000package reflect2 type safeStructType struct { safeType } func (type2 *safeStructType) FieldByName(name string) StructField { field, found := type2.Type.FieldByName(name) if !found { panic("field " + name + " not found") } return &safeField{StructField: field} }golang-github-modern-go-reflect2-1.0.0/safe_type.go000066400000000000000000000033641324545112400221450ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type safeType struct { reflect.Type cfg *frozenConfig } func (type2 *safeType) New() interface{} { return reflect.New(type2.Type).Interface() } func (type2 *safeType) UnsafeNew() unsafe.Pointer { panic("does not support unsafe operation") } func (type2 *safeType) Elem() Type { return type2.cfg.Type2(type2.Type.Elem()) } func (type2 *safeType) Type1() reflect.Type { return type2.Type } func (type2 *safeType) PackEFace(ptr unsafe.Pointer) interface{} { panic("does not support unsafe operation") } func (type2 *safeType) Implements(thatType Type) bool { return type2.Type.Implements(thatType.Type1()) } func (type2 *safeType) RType() uintptr { panic("does not support unsafe operation") } func (type2 *safeType) Indirect(obj interface{}) interface{} { return reflect.Indirect(reflect.ValueOf(obj)).Interface() } func (type2 *safeType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { panic("does not support unsafe operation") } func (type2 *safeType) LikePtr() bool { panic("does not support unsafe operation") } func (type2 *safeType) IsNullable() bool { return IsNullable(type2.Kind()) } func (type2 *safeType) IsNil(obj interface{}) bool { if obj == nil { return true } return reflect.ValueOf(obj).Elem().IsNil() } func (type2 *safeType) UnsafeIsNil(ptr unsafe.Pointer) bool { panic("does not support unsafe operation") } func (type2 *safeType) Set(obj interface{}, val interface{}) { reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(val).Elem()) } func (type2 *safeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { panic("does not support unsafe operation") } func (type2 *safeType) AssignableTo(anotherType Type) bool { return type2.Type1().AssignableTo(anotherType.Type1()) }golang-github-modern-go-reflect2-1.0.0/test15/000077500000000000000000000000001324545112400207565ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/test15/map_test.go000066400000000000000000000004571324545112400231270ustar00rootroot00000000000000package test import ( "testing" "github.com/modern-go/reflect2" ) func Test_map(t *testing.T) { var pInt = func(val int) *int { return &val } valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType) m := map[int]int{} valType.SetIndex(&m, pInt(1), pInt(1)) if m[1] != 1 { t.Fail() } }golang-github-modern-go-reflect2-1.0.0/tests/000077500000000000000000000000001324545112400207735ustar00rootroot00000000000000golang-github-modern-go-reflect2-1.0.0/tests/array_test.go000066400000000000000000000016571324545112400235100ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_array(t *testing.T) { var pInt = func(val int) *int { return &val } t.Run("New", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([2]int{}) obj := valType.New() (*(obj.(*[2]int)))[0] = 100 (*(obj.(*[2]int)))[1] = 200 return obj })) t.Run("Indirect", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([2]int{}) return valType.Indirect(&[2]int{}) })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := [2]int{} valType := api.TypeOf(obj).(reflect2.ArrayType) valType.SetIndex(&obj, 0, pInt(100)) valType.SetIndex(&obj, 1, pInt(200)) return obj })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := [2]int{1, 2} valType := api.TypeOf(obj).(reflect2.ArrayType) return []interface{} { valType.GetIndex(&obj, 0), valType.GetIndex(&obj, 1), } })) } golang-github-modern-go-reflect2-1.0.0/tests/int_test.go000066400000000000000000000017371324545112400231630ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test" "unsafe" "github.com/modern-go/test/must" "context" ) func Test_int(t *testing.T) { t.Run("New", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(1) obj := valType.New() *obj.(*int) = 100 return obj })) t.Run("PackEFace", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(1) hundred := 100 must.Equal(&hundred, valType.PackEFace(unsafe.Pointer(&hundred))) })) t.Run("Indirect", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(1) hundred := 100 must.Equal(100, valType.Indirect(&hundred)) })) t.Run("Indirect", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(1) hundred := 100 must.Equal(100, valType.UnsafeIndirect(unsafe.Pointer(&hundred))) })) t.Run("Set", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(1) i := 1 j := 10 valType.Set(&i, &j) return i })) } golang-github-modern-go-reflect2-1.0.0/tests/map_elem_array_test.go000066400000000000000000000027241324545112400253430ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_map_elem_array(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int][2]*int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, [2]*int{(*int)(reflect2.PtrOf(1)), (*int)(reflect2.PtrOf(2))}) valType.SetIndex(obj, 3, [2]*int{(*int)(reflect2.PtrOf(3)), (*int)(reflect2.PtrOf(4))}) return obj })) t.Run("SetIndex zero length array", testOp(func(api reflect2.API) interface{} { obj := map[int][0]*int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, [0]*int{}) valType.SetIndex(obj, 3, [0]*int{}) return obj })) t.Run("SetIndex single ptr array", testOp(func(api reflect2.API) interface{} { obj := map[int][1]*int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, [1]*int{(*int)(reflect2.PtrOf(1))}) valType.SetIndex(obj, 3, [1]*int{}) return obj })) t.Run("SetIndex single chan array", testOp(func(api reflect2.API) interface{} { obj := map[int][1]chan int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, [1]chan int{}) valType.SetIndex(obj, 3, [1]chan int{}) return obj })) t.Run("SetIndex single func array", testOp(func(api reflect2.API) interface{} { obj := map[int][1]func(){} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, [1]func(){}) valType.SetIndex(obj, 3, [1]func(){}) return obj })) } golang-github-modern-go-reflect2-1.0.0/tests/map_elem_bytes_test.go000066400000000000000000000021241324545112400253450ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test" "github.com/modern-go/test/must" "context" ) func Test_map_elem_bytes(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int][]byte{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, []byte("hello")) valType.SetIndex(obj, 3, nil) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := map[int][]byte{} valType := reflect2.TypeOf(obj).(reflect2.MapType) hello := []byte("hello") valType.UnsafeSetIndex(reflect2.PtrOf(obj), reflect2.PtrOf(2), reflect2.PtrOf(hello)) valType.UnsafeSetIndex(reflect2.PtrOf(obj), reflect2.PtrOf(3), nil) must.Equal([]byte("hello"), obj[2]) must.Nil(obj[3]) })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := map[int][]byte{2: []byte("hello")} valType := reflect2.TypeOf(obj).(reflect2.MapType) elem := valType.UnsafeGetIndex(reflect2.PtrOf(obj), reflect2.PtrOf(2)) must.Equal([]byte("hello"), valType.Elem().PackEFace(elem)) })) } golang-github-modern-go-reflect2-1.0.0/tests/map_elem_eface_test.go000066400000000000000000000026131324545112400252650ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test/must" "github.com/modern-go/test" "context" ) func Test_map_elem_eface(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int]interface{}{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, 4) valType.SetIndex(obj, 3, nil) return obj })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int]interface{}{3: 9, 2: nil} valType := api.TypeOf(obj).(reflect2.MapType) return []interface{}{ valType.GetIndex(obj, 3), valType.GetIndex(obj, 2), valType.GetIndex(obj, 0), } })) t.Run("TryGetIndex", test.Case(func(ctx context.Context) { obj := map[int]interface{}{3: 9, 2: nil} valType := reflect2.TypeOf(obj).(reflect2.MapType) elem, found := valType.TryGetIndex(obj, 3) must.Equal(9, elem) must.Pass(found) elem, found = valType.TryGetIndex(obj, 2) must.Nil(elem) must.Pass(found) elem, found = valType.TryGetIndex(obj, 0) must.Nil(elem) must.Pass(!found) })) t.Run("Iterate", testOp(func(api reflect2.API) interface{} { obj := map[int]interface{}{2: 4} valType := api.TypeOf(obj).(reflect2.MapType) iter := valType.Iterate(obj) must.Pass(iter.HasNext(), "api", api) key1, elem1 := iter.Next() must.Pass(!iter.HasNext(), "api", api) return []interface{}{key1, elem1} })) }golang-github-modern-go-reflect2-1.0.0/tests/map_elem_map_test.go000066400000000000000000000010441324545112400247740ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_map_elem_map(t *testing.T) { var pInt = func(val int) *int { return &val } var pMap = func(val map[int]int) *map[int]int { return &val } t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int]map[int]int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(&obj, pInt(2), pMap(map[int]int{4:4})) valType.SetIndex(&obj, pInt(3), pMap(map[int]int{9:9})) valType.SetIndex(&obj, pInt(3), pMap(nil)) return obj })) }golang-github-modern-go-reflect2-1.0.0/tests/map_elem_struct_test.go000066400000000000000000000030741324545112400255500ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "time" ) func Test_map_elem_struct(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int]time.Time{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, time.Time{}) valType.SetIndex(obj, 3, time.Time{}) return obj })) t.Run("SetIndex single ptr struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 *int } obj := map[int]TestObject{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, TestObject{}) valType.SetIndex(obj, 3, TestObject{}) return obj })) t.Run("SetIndex single map struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 map[int]int } obj := map[int]TestObject{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, TestObject{}) valType.SetIndex(obj, 3, TestObject{}) return obj })) t.Run("SetIndex single chan struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 chan int } obj := map[int]TestObject{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, TestObject{}) valType.SetIndex(obj, 3, TestObject{}) return obj })) t.Run("SetIndex single func struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 func() } obj := map[int]TestObject{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, 2, TestObject{}) valType.SetIndex(obj, 3, TestObject{}) return obj })) } golang-github-modern-go-reflect2-1.0.0/tests/map_key_eface_test.go000066400000000000000000000023141324545112400251310ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test/must" ) func Test_map_key_eface(t *testing.T) { var pEFace = func(val interface{}) interface{} { return &val } var pInt = func(val int) *int { return &val } t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[interface{}]int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(&obj, pEFace(2), pInt(4)) valType.SetIndex(&obj, pEFace(3), pInt(9)) valType.SetIndex(&obj, pEFace(nil), pInt(9)) return obj })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := map[interface{}]int{3: 9, 2: 4} valType := api.TypeOf(obj).(reflect2.MapType) return []interface{}{ valType.GetIndex(&obj, pEFace(3)), valType.GetIndex(&obj, pEFace(0)), valType.GetIndex(&obj, pEFace(nil)), valType.GetIndex(&obj, pEFace("")), } })) t.Run("Iterate", testOp(func(api reflect2.API) interface{} { obj := map[interface{}]int{2: 4} valType := api.TypeOf(obj).(reflect2.MapType) iter := valType.Iterate(obj) must.Pass(iter.HasNext(), "api", api) key1, elem1 := iter.Next() must.Pass(!iter.HasNext(), "api", api) return []interface{}{key1, elem1} })) } golang-github-modern-go-reflect2-1.0.0/tests/map_key_iface_test.go000066400000000000000000000022561324545112400251420ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test/must" ) type intError int func (err intError) Error() string { return "" } func Test_map_iface_key(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[error]int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(obj, intError(2), 4) valType.SetIndex(obj, intError(2), 9) valType.SetIndex(obj, nil, 9) must.Panic(func() { valType.SetIndex(obj, "", 9) }) return obj })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := map[error]int{intError(3): 9, intError(2): 4} valType := api.TypeOf(obj).(reflect2.MapType) must.Panic(func() { valType.GetIndex(obj, "") }) return []interface{}{ valType.GetIndex(obj, intError(3)), valType.GetIndex(obj, nil), } })) t.Run("Iterate", testOp(func(api reflect2.API) interface{} { obj := map[error]int{intError(2): 4} valType := api.TypeOf(obj).(reflect2.MapType) iter := valType.Iterate(obj) must.Pass(iter.HasNext(), "api", api) key1, elem1 := iter.Next() must.Pass(!iter.HasNext(), "api", api) return []interface{}{key1, elem1} })) } golang-github-modern-go-reflect2-1.0.0/tests/map_key_ptr_test.go000066400000000000000000000026031324545112400246740ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test/must" "github.com/modern-go/test" "unsafe" "context" ) func Test_map_key_ptr(t *testing.T) { var pInt = func(val int) *int { return &val } t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[*int]int{} valType := api.TypeOf(obj).(reflect2.MapType) key := pInt(2) valType.SetIndex(obj, &key, 4) valType.SetIndex(obj, &key, 9) //valType.SetIndex(obj, nil, 9) return obj[pInt(2)] })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := map[*int]int{} valType := reflect2.TypeOf(obj).(reflect2.MapType) v := pInt(2) valType.UnsafeSetIndex(reflect2.PtrOf(obj), unsafe.Pointer(v), reflect2.PtrOf(4)) must.Equal(4, obj[v]) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := map[*int]int{pInt(3): 9, pInt(2): 4} valType := api.TypeOf(obj).(reflect2.MapType) return []interface{}{ valType.GetIndex(obj, pInt(3)), valType.GetIndex(obj, pInt(2)), valType.GetIndex(obj, nil), } })) t.Run("Iterate", testOp(func(api reflect2.API) interface{} { obj := map[*int]int{pInt(2): 4} valType := api.TypeOf(obj).(reflect2.MapType) iter := valType.Iterate(&obj) must.Pass(iter.HasNext(), "api", api) key1, elem1 := iter.Next() must.Pass(!iter.HasNext(), "api", api) return []interface{}{key1, elem1} })) } golang-github-modern-go-reflect2-1.0.0/tests/map_test.go000066400000000000000000000070221324545112400231370ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test/must" "github.com/modern-go/test" "unsafe" "reflect" "context" ) func Test_map(t *testing.T) { var pInt = func(val int) *int { return &val } t.Run("New", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(map[int]int{}) m := valType.New().(*map[int]int) return m })) t.Run("IsNil", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(map[int]int{}) var nilMap map[int]int m := map[int]int{} return []interface{}{ valType.IsNil(&nilMap), valType.IsNil(&m), } })) t.Run("MakeMap", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(map[int]int{}).(reflect2.MapType) m := *(valType.MakeMap(0).(*map[int]int)) m[2] = 4 m[3] = 9 return m })) t.Run("UnsafeMakeMap", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType) m := *(*map[int]int)(valType.UnsafeMakeMap(0)) m[2] = 4 m[3] = 9 })) t.Run("PackEFace", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(map[int]int{}).(reflect2.MapType) m := valType.UnsafeMakeMap(0) must.Equal(&map[int]int{}, valType.PackEFace(unsafe.Pointer(m))) })) t.Run("Indirect", testOp(func(api reflect2.API) interface{} { valType := reflect2.TypeOf(map[int]int{}) return valType.Indirect(&map[int]int{}) })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int]int{} valType := api.TypeOf(obj).(reflect2.MapType) valType.SetIndex(&obj, pInt(2), pInt(4)) valType.SetIndex(&obj, pInt(3), pInt(9)) must.Equal(4, obj[2]) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := map[int]int{} valType := reflect2.TypeOf(obj).(reflect2.MapType) valType.UnsafeSetIndex(unsafe.Pointer(&obj), reflect2.PtrOf(2), reflect2.PtrOf(4)) must.Equal(map[int]int{2: 4}, obj) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := map[int]int{3: 9, 2: 4} valType := api.TypeOf(obj).(reflect2.MapType) return []interface{}{ *valType.GetIndex(&obj, pInt(3)).(*int), valType.GetIndex(&obj, pInt(0)).(*int), } })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := map[int]int{3: 9, 2: 4} valType := reflect2.TypeOf(obj).(reflect2.MapType) elem := valType.UnsafeGetIndex(unsafe.Pointer(&obj), reflect2.PtrOf(3)) must.Equal(9, *(*int)(elem)) })) t.Run("Iterate", testOp(func(api reflect2.API) interface{} { obj := map[int]int{2: 4} valType := api.TypeOf(obj).(reflect2.MapType) iter := valType.Iterate(&obj) must.Pass(iter.HasNext(), "api", api) key1, elem1 := iter.Next() must.Pass(!iter.HasNext(), "api", api) return []interface{}{key1, elem1} })) t.Run("UnsafeIterate", test.Case(func(ctx context.Context) { obj := map[int]int{2: 4} valType := reflect2.TypeOf(obj).(reflect2.MapType) iter := valType.UnsafeIterate(unsafe.Pointer(&obj)) must.Pass(iter.HasNext()) key, elem := iter.UnsafeNext() must.Equal(2, *(*int)(key)) must.Equal(4, *(*int)(elem)) })) } func Benchmark_map_unsafe(b *testing.B) { obj := map[int]int{} valType := reflect2.TypeOf(obj).(*reflect2.UnsafeMapType) m := unsafe.Pointer(&obj) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { valType.UnsafeSetIndex(m, reflect2.PtrOf(2), reflect2.PtrOf(4)) } } func Benchmark_map_safe(b *testing.B) { obj := map[int]int{} val := reflect.ValueOf(obj) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { val.SetMapIndex(reflect.ValueOf(2), reflect.ValueOf(4)) } } golang-github-modern-go-reflect2-1.0.0/tests/op_test.go000066400000000000000000000006061324545112400230010ustar00rootroot00000000000000package tests import ( "github.com/modern-go/reflect2" "testing" "github.com/modern-go/test/must" "github.com/modern-go/test" "context" ) func testOp(f func(api reflect2.API) interface{}) func(t *testing.T) { return test.Case(func(ctx context.Context) { unsafeResult := f(reflect2.ConfigUnsafe) safeResult := f(reflect2.ConfigSafe) must.Equal(safeResult, unsafeResult) }) } golang-github-modern-go-reflect2-1.0.0/tests/slice_array_test.go000066400000000000000000000021401324545112400246530ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_slice_array(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := [][1]int{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, [1]int{1}) valType.SetIndex(obj, 1, [1]int{2}) return obj })) t.Run("SetIndex single ptr struct", testOp(func(api reflect2.API) interface{} { obj := [][1]*int{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, [1]*int{}) valType.SetIndex(obj, 1, [1]*int{}) return obj })) t.Run("SetIndex single chan struct", testOp(func(api reflect2.API) interface{} { obj := [][1]chan int{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, [1]chan int{}) valType.SetIndex(obj, 1, [1]chan int{}) return obj })) t.Run("SetIndex single func struct", testOp(func(api reflect2.API) interface{} { obj := [][1]func(){{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, [1]func(){}) valType.SetIndex(obj, 1, [1]func(){}) return obj })) } golang-github-modern-go-reflect2-1.0.0/tests/slice_bytes_test.go000066400000000000000000000005741324545112400246740ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_slice_bytes(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := [][]byte{[]byte("hello"), []byte("world")} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(&obj, 0, []byte("hi")) valType.SetIndex(&obj, 1, []byte("there")) return obj })) }golang-github-modern-go-reflect2-1.0.0/tests/slice_eface_test.go000066400000000000000000000045561324545112400246150ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test" "github.com/modern-go/test/must" "unsafe" "github.com/modern-go/test/should" "fmt" "context" ) func Test_slice_eface(t *testing.T) { t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]interface{}{}).(reflect2.SliceType) obj := valType.MakeSlice(5, 10) obj.([]interface{})[0] = 100 obj.([]interface{})[4] = 20 return obj })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []interface{}{1, nil} valType := api.TypeOf(obj).(reflect2.SliceType) elem0 := interface{}(100) valType.SetIndex(obj, 0, &elem0) elem1 := interface{}(20) valType.SetIndex(obj, 1, &elem1) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := []interface{}{1, 2} valType := reflect2.TypeOf(obj).(reflect2.SliceType) var elem0 interface{} = 100 valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(&elem0)) var elem1 interface{} = 10 valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(&elem1)) must.Equal([]interface{}{100, 10}, obj) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := []interface{}{1, nil} valType := api.TypeOf(obj).(reflect2.SliceType) fmt.Println(api, *valType.GetIndex(obj, 0).(*interface{})) return []interface{}{ valType.GetIndex(obj, 0), valType.GetIndex(obj, 1), } })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := []interface{}{1, nil} valType := reflect2.TypeOf(obj).(reflect2.SliceType) elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0) must.Equal(1, *(*interface{})(elem0)) })) t.Run("Append", testOp(func(api reflect2.API) interface{} { obj := make([]interface{}, 2, 3) obj[0] = 1 obj[1] = 2 valType := api.TypeOf(obj).(reflect2.SliceType) valType.Append(&obj, 3) // will trigger grow valType.Append(&obj, 4) return obj })) t.Run("UnsafeAppend", test.Case(func(ctx context.Context) { obj := make([]interface{}, 2, 3) obj[0] = 1 obj[1] = 2 valType := reflect2.TypeOf(obj).(reflect2.SliceType) ptr := reflect2.PtrOf(obj) var elem2 interface{} = 3 valType.UnsafeAppend(ptr, unsafe.Pointer(&elem2)) var elem3 interface{} = 4 valType.UnsafeAppend(ptr, unsafe.Pointer(&elem3)) should.Equal([]interface{}{1, 2, 3, 4}, valType.PackEFace(ptr)) })) } golang-github-modern-go-reflect2-1.0.0/tests/slice_iface_test.go000066400000000000000000000047411324545112400246150ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "errors" "github.com/modern-go/test" "unsafe" "github.com/modern-go/test/must" "context" ) func Test_slice_iface(t *testing.T) { var pError = func(msg string) *error { err := errors.New(msg) return &err } t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]error{}).(reflect2.SliceType) obj := *(valType.MakeSlice(5, 10).(*[]error)) obj[0] = errors.New("hello") obj[4] = errors.New("world") return obj })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []error{errors.New("hello"), nil} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(&obj, 0, pError("hi")) valType.SetIndex(&obj, 1, pError("world")) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := []error{errors.New("hello"), nil} valType := reflect2.TypeOf(obj).(reflect2.SliceType) elem0 := errors.New("hi") valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(&elem0)) elem1 := errors.New("world") valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(&elem1)) must.Equal([]error{elem0, elem1}, obj) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := []error{errors.New("hello"), nil} valType := api.TypeOf(obj).(reflect2.SliceType) return []interface{}{ valType.GetIndex(&obj, 0), valType.GetIndex(&obj, 1), } })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := []error{errors.New("hello"), nil} valType := reflect2.TypeOf(obj).(reflect2.SliceType) elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0) must.Equal(errors.New("hello"), *(*error)(elem0)) })) t.Run("Append", testOp(func(api reflect2.API) interface{} { obj := make([]error, 2, 3) obj[0] = errors.New("1") obj[1] = errors.New("2") valType := api.TypeOf(obj).(reflect2.SliceType) ptr := &obj valType.Append(ptr, pError("3")) // will trigger grow valType.Append(ptr, pError("4")) return ptr })) t.Run("UnsafeAppend", test.Case(func(ctx context.Context) { obj := make([]error, 2, 3) obj[0] = errors.New("1") obj[1] = errors.New("2") valType := reflect2.TypeOf(obj).(reflect2.SliceType) ptr := reflect2.PtrOf(obj) elem2 := errors.New("3") valType.UnsafeAppend(ptr, unsafe.Pointer(&elem2)) elem3 := errors.New("4") valType.UnsafeAppend(ptr, unsafe.Pointer(&elem3)) must.Equal(&[]error{ obj[0], obj[1], elem2, elem3, }, valType.PackEFace(ptr)) })) } golang-github-modern-go-reflect2-1.0.0/tests/slice_map_test.go000066400000000000000000000023511324545112400243160ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_slice_map(t *testing.T) { t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]map[int]int{}).(reflect2.SliceType) obj := valType.MakeSlice(5, 10) obj.([]map[int]int)[0] = map[int]int{1:1} obj.([]map[int]int)[4] = map[int]int{2:2} return obj })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []map[int]int{{1: 1}, nil} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, &map[int]int{10:10}) valType.SetIndex(obj, 1, &map[int]int{2:2}) return obj })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := []map[int]int{{1:1}, nil} valType := api.TypeOf(obj).(reflect2.SliceType) return []interface{}{ valType.GetIndex(&obj, 0), valType.GetIndex(&obj, 1), valType.GetIndex(obj, 0), valType.GetIndex(obj, 1), } })) t.Run("Append", testOp(func(api reflect2.API) interface{} { obj := make([]map[int]int, 2, 3) obj[0] = map[int]int{1:1} obj[1] = map[int]int{2:2} valType := api.TypeOf(obj).(reflect2.SliceType) valType.Append(obj, map[int]int{3:3}) // will trigger grow valType.Append(obj, map[int]int{4:4}) return obj })) }golang-github-modern-go-reflect2-1.0.0/tests/slice_ptr_test.go000066400000000000000000000031271324545112400243500ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test" "unsafe" "github.com/modern-go/test/must" "context" ) func Test_slice_ptr(t *testing.T) { var pInt = func(val int) *int { return &val } t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]*int{}).(reflect2.SliceType) obj := valType.MakeSlice(5, 10) obj.([]*int)[0] = pInt(1) obj.([]*int)[4] = pInt(5) return obj })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []*int{pInt(1), nil} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, pInt(2)) valType.SetIndex(obj, 1, pInt(3)) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := []*int{pInt(1), nil} valType := reflect2.TypeOf(obj).(reflect2.SliceType) valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, unsafe.Pointer(pInt(2))) valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, unsafe.Pointer(pInt(1))) must.Equal([]*int{pInt(2), pInt(1)}, obj) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := []*int{pInt(1), nil} valType := api.TypeOf(obj).(reflect2.SliceType) return []interface{}{ valType.GetIndex(&obj, 0), valType.GetIndex(&obj, 1), valType.GetIndex(obj, 0), valType.GetIndex(obj, 1), } })) t.Run("Append", testOp(func(api reflect2.API) interface{} { obj := make([]*int, 2, 3) obj[0] = pInt(1) obj[1] = pInt(2) valType := api.TypeOf(obj).(reflect2.SliceType) valType.Append(obj, pInt(3)) // will trigger grow valType.Append(obj, pInt(4)) return obj })) } golang-github-modern-go-reflect2-1.0.0/tests/slice_string_test.go000066400000000000000000000005351324545112400250510ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_slice_string(t *testing.T) { t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []string{"hello", "world"} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(&obj, 0, "hi") valType.SetIndex(&obj, 1, "there") return obj })) }golang-github-modern-go-reflect2-1.0.0/tests/slice_struct_test.go000066400000000000000000000026221324545112400250660ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_slice_struct(t *testing.T) { var pInt = func(val int) *int { return &val } t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 float64 Field2 float64 } obj := []TestObject{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, &TestObject{1, 3}) valType.SetIndex(obj, 1, &TestObject{2, 4}) return obj })) t.Run("SetIndex single ptr struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 *int } obj := []TestObject{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, &TestObject{pInt(1)}) valType.SetIndex(obj, 1, &TestObject{pInt(2)}) return obj })) t.Run("SetIndex single chan struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 chan int } obj := []TestObject{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, TestObject{}) valType.SetIndex(obj, 1, TestObject{}) return obj })) t.Run("SetIndex single func struct", testOp(func(api reflect2.API) interface{} { type TestObject struct { Field1 func() } obj := []TestObject{{}, {}} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(obj, 0, TestObject{}) valType.SetIndex(obj, 1, TestObject{}) return obj })) }golang-github-modern-go-reflect2-1.0.0/tests/slice_test.go000066400000000000000000000064171324545112400234700ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test" "github.com/modern-go/test/must" "context" ) func Test_slice(t *testing.T) { var pInt = func(val int) *int { return &val } t.Run("New", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]int{}) obj := *valType.New().(*[]int) obj = append(obj, 1) return obj })) t.Run("IsNil", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]int{}) var nilSlice []int s := []int{} return []interface{}{ valType.IsNil(&nilSlice), valType.IsNil(&s), valType.IsNil(nil), } })) t.Run("SetNil", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]int{}).(reflect2.SliceType) s := []int{1} valType.SetNil(&s) return s })) t.Run("Set", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]int{}).(reflect2.SliceType) s1 := []int{1} s2 := []int{2} valType.Set(&s1, &s2) return s1 })) t.Run("MakeSlice", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf([]int{}).(reflect2.SliceType) obj := *(valType.MakeSlice(5, 10).(*[]int)) obj[0] = 100 obj[4] = 20 return obj })) t.Run("UnsafeMakeSlice", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf([]int{}).(reflect2.SliceType) obj := valType.UnsafeMakeSlice(5, 10) must.Equal(&[]int{0, 0, 0, 0, 0}, valType.PackEFace(obj)) })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { obj := []int{1, 2} valType := api.TypeOf(obj).(reflect2.SliceType) valType.SetIndex(&obj, 0, pInt(100)) valType.SetIndex(&obj, 1, pInt(20)) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { obj := []int{1, 2} valType := reflect2.TypeOf(obj).(reflect2.SliceType) valType.UnsafeSetIndex(reflect2.PtrOf(obj), 0, reflect2.PtrOf(100)) valType.UnsafeSetIndex(reflect2.PtrOf(obj), 1, reflect2.PtrOf(10)) must.Equal([]int{100, 10}, obj) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := []int{1, 2} valType := api.TypeOf(obj).(reflect2.SliceType) return []interface{}{ valType.GetIndex(&obj, 1).(*int), } })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := []int{1, 2} valType := reflect2.TypeOf(obj).(reflect2.SliceType) elem0 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 0) must.Equal(1, *(*int)(elem0)) elem1 := valType.UnsafeGetIndex(reflect2.PtrOf(obj), 1) must.Equal(2, *(*int)(elem1)) })) t.Run("Append", testOp(func(api reflect2.API) interface{} { obj := make([]int, 2, 3) obj[0] = 1 obj[1] = 2 valType := api.TypeOf(obj).(reflect2.SliceType) ptr := &obj valType.Append(ptr, pInt(3)) // will trigger grow valType.Append(ptr, pInt(4)) return ptr })) t.Run("UnsafeAppend", test.Case(func(ctx context.Context) { obj := make([]int, 2, 3) obj[0] = 1 obj[1] = 2 valType := reflect2.TypeOf(obj).(reflect2.SliceType) ptr := reflect2.PtrOf(obj) valType.UnsafeAppend(ptr, reflect2.PtrOf(3)) valType.UnsafeAppend(ptr, reflect2.PtrOf(4)) must.Equal(&[]int{1, 2, 3, 4}, valType.PackEFace(ptr)) })) t.Run("Grow", testOp(func(api reflect2.API) interface{} { obj := make([]int, 2, 3) obj[0] = 1 obj[1] = 2 valType := reflect2.TypeOf(obj).(reflect2.SliceType) valType.Grow(&obj, 4) return obj })) } golang-github-modern-go-reflect2-1.0.0/tests/struct_eface_test.go000066400000000000000000000012551324545112400250330ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" ) func Test_struct_eface(t *testing.T) { type TestObject struct { Field1 interface{} } var pEFace = func(val interface{}) interface{} { return &val } t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(TestObject{}).(reflect2.StructType) field1 := valType.FieldByName("Field1") obj := TestObject{} field1.Set(&obj, pEFace(100)) return obj })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := TestObject{Field1: 100} valType := api.TypeOf(obj).(reflect2.StructType) field1 := valType.FieldByName("Field1") return field1.Get(&obj) })) }golang-github-modern-go-reflect2-1.0.0/tests/struct_ptr_test.go000066400000000000000000000011031324545112400245650ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test/must" "github.com/modern-go/test" "context" ) func Test_struct_ptr(t *testing.T) { type TestObject struct { Field1 *int } t.Run("PackEFace", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(TestObject{}) ptr := valType.UnsafeNew() must.Equal(&TestObject{}, valType.PackEFace(ptr)) })) t.Run("Indirect", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(TestObject{}) must.Equal(TestObject{}, valType.Indirect(&TestObject{})) })) }golang-github-modern-go-reflect2-1.0.0/tests/struct_test.go000066400000000000000000000035251324545112400237120ustar00rootroot00000000000000package tests import ( "testing" "github.com/modern-go/reflect2" "github.com/modern-go/test" "unsafe" "github.com/modern-go/test/must" "context" ) func Test_struct(t *testing.T) { type TestObject struct { Field1 int Field2 int } var pInt = func(val int) *int { return &val } t.Run("New", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(TestObject{}) obj := valType.New() obj.(*TestObject).Field1 = 20 obj.(*TestObject).Field2 = 100 return obj })) t.Run("PackEFace", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(TestObject{}) ptr := valType.UnsafeNew() must.Equal(&TestObject{}, valType.PackEFace(ptr)) })) t.Run("Indirect", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(TestObject{}) must.Equal(TestObject{}, valType.Indirect(&TestObject{})) })) t.Run("SetIndex", testOp(func(api reflect2.API) interface{} { valType := api.TypeOf(TestObject{}).(reflect2.StructType) field1 := valType.FieldByName("Field1") obj := TestObject{} field1.Set(&obj, pInt(100)) return obj })) t.Run("UnsafeSetIndex", test.Case(func(ctx context.Context) { valType := reflect2.TypeOf(TestObject{}).(reflect2.StructType) field1 := valType.FieldByName("Field1") obj := TestObject{} field1.UnsafeSet(unsafe.Pointer(&obj), reflect2.PtrOf(100)) must.Equal(100, obj.Field1) })) t.Run("GetIndex", testOp(func(api reflect2.API) interface{} { obj := TestObject{Field1: 100} valType := api.TypeOf(obj).(reflect2.StructType) field1 := valType.FieldByName("Field1") return field1.Get(&obj) })) t.Run("UnsafeGetIndex", test.Case(func(ctx context.Context) { obj := TestObject{Field1: 100} valType := reflect2.TypeOf(obj).(reflect2.StructType) field1 := valType.FieldByName("Field1") value := field1.UnsafeGet(unsafe.Pointer(&obj)) must.Equal(100, *(*int)(value)) })) } golang-github-modern-go-reflect2-1.0.0/type_map.go000066400000000000000000000034251324545112400220020ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" "runtime" "strings" ) // typelinks1 for 1.5 ~ 1.6 //go:linkname typelinks1 reflect.typelinks func typelinks1() [][]unsafe.Pointer // typelinks2 for 1.7 ~ //go:linkname typelinks2 reflect.typelinks func typelinks2() (sections []unsafe.Pointer, offset [][]int32) var types = map[string]reflect.Type{} func init() { ver := runtime.Version() if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") { loadGo15Types() } else if ver == "go1.6" || strings.HasPrefix(ver, "go1.6.") { loadGo15Types() } else { loadGo17Types() } } func loadGo15Types() { var obj interface{} = reflect.TypeOf(0) typePtrss := typelinks1() for _, typePtrs := range typePtrss { for _, typePtr := range typePtrs { (*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr typ := obj.(reflect.Type) if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { types[typ.Elem().String()] = typ.Elem() } if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr && typ.Elem().Elem().Kind() == reflect.Struct { types[typ.Elem().Elem().String()] = typ.Elem().Elem() } } } } func loadGo17Types() { var obj interface{} = reflect.TypeOf(0) sections, offset := typelinks2() for i, offs := range offset { rodata := sections[i] for _, off := range offs { (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off) typ := obj.(reflect.Type) if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct { types[typ.Elem().String()] = typ.Elem() } } } } type emptyInterface struct { typ unsafe.Pointer word unsafe.Pointer } // TypeByName return the type by its name, just like Class.forName in java func TypeByName(typeName string) Type { return Type2(types[typeName]) } golang-github-modern-go-reflect2-1.0.0/unsafe_array.go000066400000000000000000000037551324545112400226510ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" ) type UnsafeArrayType struct { unsafeType elemRType unsafe.Pointer pElemRType unsafe.Pointer elemSize uintptr likePtr bool } func newUnsafeArrayType(cfg *frozenConfig, type1 reflect.Type) *UnsafeArrayType { return &UnsafeArrayType{ unsafeType: *newUnsafeType(cfg, type1), elemRType: unpackEFace(type1.Elem()).data, pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, elemSize: type1.Elem().Size(), likePtr: likePtrType(type1), } } func (type2 *UnsafeArrayType) LikePtr() bool { return type2.likePtr } func (type2 *UnsafeArrayType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *UnsafeArrayType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { if type2.likePtr { return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) } return packEFace(type2.rtype, ptr) } func (type2 *UnsafeArrayType) SetIndex(obj interface{}, index int, elem interface{}) { objEFace := unpackEFace(obj) assertType("ArrayType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) elemEFace := unpackEFace(elem) assertType("ArrayType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) } func (type2 *UnsafeArrayType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { elemPtr := arrayAt(obj, index, type2.elemSize, "i < s.Len") typedmemmove(type2.elemRType, elemPtr, elem) } func (type2 *UnsafeArrayType) GetIndex(obj interface{}, index int) interface{} { objEFace := unpackEFace(obj) assertType("ArrayType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) elemPtr := type2.UnsafeGetIndex(objEFace.data, index) return packEFace(type2.pElemRType, elemPtr) } func (type2 *UnsafeArrayType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { return arrayAt(obj, index, type2.elemSize, "i < s.Len") } golang-github-modern-go-reflect2-1.0.0/unsafe_eface.go000066400000000000000000000024241324545112400225660ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" ) type eface struct { rtype unsafe.Pointer data unsafe.Pointer } func unpackEFace(obj interface{}) *eface { return (*eface)(unsafe.Pointer(&obj)) } func packEFace(rtype unsafe.Pointer, data unsafe.Pointer) interface{} { var i interface{} e := (*eface)(unsafe.Pointer(&i)) e.rtype = rtype e.data = data return i } type UnsafeEFaceType struct { unsafeType } func newUnsafeEFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeEFaceType { return &UnsafeEFaceType{ unsafeType: *newUnsafeType(cfg, type1), } } func (type2 *UnsafeEFaceType) IsNil(obj interface{}) bool { if obj == nil { return true } objEFace := unpackEFace(obj) assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIsNil(objEFace.data) } func (type2 *UnsafeEFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { if ptr == nil { return true } return unpackEFace(*(*interface{})(ptr)).data == nil } func (type2 *UnsafeEFaceType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *UnsafeEFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { return *(*interface{})(ptr) }golang-github-modern-go-reflect2-1.0.0/unsafe_field.go000066400000000000000000000041321324545112400226040ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type UnsafeStructField struct { reflect.StructField structType *UnsafeStructType rtype unsafe.Pointer ptrRType unsafe.Pointer } func newUnsafeStructField(structType *UnsafeStructType, structField reflect.StructField) *UnsafeStructField { return &UnsafeStructField{ StructField: structField, rtype: unpackEFace(structField.Type).data, ptrRType: unpackEFace(reflect.PtrTo(structField.Type)).data, structType: structType, } } func (field *UnsafeStructField) Offset() uintptr { return field.StructField.Offset } func (field *UnsafeStructField) Name() string { return field.StructField.Name } func (field *UnsafeStructField) PkgPath() string { return field.StructField.PkgPath } func (field *UnsafeStructField) Type() Type { return field.structType.cfg.Type2(field.StructField.Type) } func (field *UnsafeStructField) Tag() reflect.StructTag { return field.StructField.Tag } func (field *UnsafeStructField) Index() []int { return field.StructField.Index } func (field *UnsafeStructField) Anonymous() bool { return field.StructField.Anonymous } func (field *UnsafeStructField) Set(obj interface{}, value interface{}) { objEFace := unpackEFace(obj) assertType("StructField.SetIndex argument 1", field.structType.ptrRType, objEFace.rtype) valueEFace := unpackEFace(value) assertType("StructField.SetIndex argument 2", field.ptrRType, valueEFace.rtype) field.UnsafeSet(objEFace.data, valueEFace.data) } func (field *UnsafeStructField) UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer) { fieldPtr := add(obj, field.StructField.Offset, "same as non-reflect &v.field") typedmemmove(field.rtype, fieldPtr, value) } func (field *UnsafeStructField) Get(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("StructField.GetIndex argument 1", field.structType.ptrRType, objEFace.rtype) value := field.UnsafeGet(objEFace.data) return packEFace(field.ptrRType, value) } func (field *UnsafeStructField) UnsafeGet(obj unsafe.Pointer) unsafe.Pointer { return add(obj, field.StructField.Offset, "same as non-reflect &v.field") } golang-github-modern-go-reflect2-1.0.0/unsafe_iface.go000066400000000000000000000024121324545112400225670ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" ) type iface struct { itab *itab data unsafe.Pointer } type itab struct { ignore unsafe.Pointer rtype unsafe.Pointer } func IFaceToEFace(ptr unsafe.Pointer) interface{} { iface := (*iface)(ptr) if iface.itab == nil { return nil } return packEFace(iface.itab.rtype, iface.data) } type UnsafeIFaceType struct { unsafeType } func newUnsafeIFaceType(cfg *frozenConfig, type1 reflect.Type) *UnsafeIFaceType { return &UnsafeIFaceType{ unsafeType: *newUnsafeType(cfg, type1), } } func (type2 *UnsafeIFaceType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *UnsafeIFaceType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { return IFaceToEFace(ptr) } func (type2 *UnsafeIFaceType) IsNil(obj interface{}) bool { if obj == nil { return true } objEFace := unpackEFace(obj) assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIsNil(objEFace.data) } func (type2 *UnsafeIFaceType) UnsafeIsNil(ptr unsafe.Pointer) bool { if ptr == nil { return true } iface := (*iface)(ptr) if iface.itab == nil { return true } return false }golang-github-modern-go-reflect2-1.0.0/unsafe_link.go000066400000000000000000000053051324545112400224610ustar00rootroot00000000000000package reflect2 import "unsafe" //go:linkname unsafe_New reflect.unsafe_New func unsafe_New(rtype unsafe.Pointer) unsafe.Pointer //go:linkname typedmemmove reflect.typedmemmove func typedmemmove(rtype unsafe.Pointer, dst, src unsafe.Pointer) //go:linkname unsafe_NewArray reflect.unsafe_NewArray func unsafe_NewArray(rtype unsafe.Pointer, length int) unsafe.Pointer // typedslicecopy copies a slice of elemType values from src to dst, // returning the number of elements copied. //go:linkname typedslicecopy reflect.typedslicecopy //go:noescape func typedslicecopy(elemType unsafe.Pointer, dst, src sliceHeader) int //go:linkname mapassign reflect.mapassign //go:noescape func mapassign(rtype unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer) //go:linkname mapaccess reflect.mapaccess //go:noescape func mapaccess(rtype unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer) // m escapes into the return value, but the caller of mapiterinit // doesn't let the return value escape. //go:noescape //go:linkname mapiterinit reflect.mapiterinit func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) *hiter //go:noescape //go:linkname mapiternext reflect.mapiternext func mapiternext(it *hiter) //go:linkname ifaceE2I reflect.ifaceE2I func ifaceE2I(rtype unsafe.Pointer, src interface{}, dst unsafe.Pointer) // A hash iteration structure. // If you modify hiter, also change cmd/internal/gc/reflect.go to indicate // the layout of this structure. type hiter struct { key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/internal/gc/range.go). value unsafe.Pointer // Must be in second position (see cmd/internal/gc/range.go). // rest fields are ignored } // add returns p+x. // // The whySafe string is ignored, so that the function still inlines // as efficiently as p+x, but all call sites should use the string to // record why the addition is safe, which is to say why the addition // does not cause x to advance to the very end of p's allocation // and therefore point incorrectly at the next block in memory. func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { return unsafe.Pointer(uintptr(p) + x) } // arrayAt returns the i-th element of p, // an array whose elements are eltSize bytes wide. // The array pointed at by p must have at least i+1 elements: // it is invalid (but impossible to check here) to pass i >= len, // because then the result will point outside the array. // whySafe must explain why i < len. (Passing "i < len" is fine; // the benefit is to surface this assumption at the call site.) func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer { return add(p, uintptr(i)*eltSize, "i < len") }golang-github-modern-go-reflect2-1.0.0/unsafe_map.go000066400000000000000000000101651324545112400223010ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type UnsafeMapType struct { unsafeType pKeyRType unsafe.Pointer pElemRType unsafe.Pointer } func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType { return &UnsafeMapType{ unsafeType: *newUnsafeType(cfg, type1), pKeyRType: unpackEFace(reflect.PtrTo(type1.Key())).data, pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data, } } func (type2 *UnsafeMapType) IsNil(obj interface{}) bool { if obj == nil { return true } objEFace := unpackEFace(obj) assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIsNil(objEFace.data) } func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool { if ptr == nil { return true } return *(*unsafe.Pointer)(ptr) == nil } func (type2 *UnsafeMapType) LikePtr() bool { return true } func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) } func (type2 *UnsafeMapType) Key() Type { return type2.cfg.Type2(type2.Type.Key()) } func (type2 *UnsafeMapType) MakeMap(cap int) interface{} { return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap)) } func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { m := makeMapWithSize(type2.rtype, cap) return unsafe.Pointer(&m) } func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { objEFace := unpackEFace(obj) assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) keyEFace := unpackEFace(key) assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype) elemEFace := unpackEFace(elem) assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data) } func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem) } func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { objEFace := unpackEFace(obj) assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype) keyEFace := unpackEFace(key) assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype) elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) if elemPtr == nil { return nil, false } return packEFace(type2.pElemRType, elemPtr), true } func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} { objEFace := unpackEFace(obj) assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) keyEFace := unpackEFace(key) assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype) elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data) return packEFace(type2.pElemRType, elemPtr) } func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key) } func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator { objEFace := unpackEFace(obj) assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIterate(objEFace.data) } func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { return &UnsafeMapIterator{ hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)), pKeyRType: type2.pKeyRType, pElemRType: type2.pElemRType, } } type UnsafeMapIterator struct { *hiter pKeyRType unsafe.Pointer pElemRType unsafe.Pointer } func (iter *UnsafeMapIterator) HasNext() bool { return iter.key != nil } func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) { key, elem := iter.UnsafeNext() return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem) } func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { key := iter.key elem := iter.value mapiternext(iter.hiter) return key, elem } golang-github-modern-go-reflect2-1.0.0/unsafe_ptr.go000066400000000000000000000020131324545112400223220ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" ) type UnsafePtrType struct { unsafeType } func newUnsafePtrType(cfg *frozenConfig, type1 reflect.Type) *UnsafePtrType { return &UnsafePtrType{ unsafeType: *newUnsafeType(cfg, type1), } } func (type2 *UnsafePtrType) IsNil(obj interface{}) bool { if obj == nil { return true } objEFace := unpackEFace(obj) assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIsNil(objEFace.data) } func (type2 *UnsafePtrType) UnsafeIsNil(ptr unsafe.Pointer) bool { if ptr == nil { return true } return *(*unsafe.Pointer)(ptr) == nil } func (type2 *UnsafePtrType) LikePtr() bool { return true } func (type2 *UnsafePtrType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *UnsafePtrType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) } golang-github-modern-go-reflect2-1.0.0/unsafe_slice.go000066400000000000000000000122561324545112400226260ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" ) // sliceHeader is a safe version of SliceHeader used within this package. type sliceHeader struct { Data unsafe.Pointer Len int Cap int } type UnsafeSliceType struct { unsafeType elemRType unsafe.Pointer pElemRType unsafe.Pointer elemSize uintptr } func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType { elemType := type1.Elem() return &UnsafeSliceType{ unsafeType: *newUnsafeType(cfg, type1), pElemRType: unpackEFace(reflect.PtrTo(elemType)).data, elemRType: unpackEFace(elemType).data, elemSize: elemType.Size(), } } func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) { objEFace := unpackEFace(obj) assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) valEFace := unpackEFace(val) assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) type2.UnsafeSet(objEFace.data, valEFace.data) } func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { *(*sliceHeader)(ptr) = *(*sliceHeader)(val) } func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool { if obj == nil { return true } objEFace := unpackEFace(obj) assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIsNil(objEFace.data) } func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool { if ptr == nil { return true } return (*sliceHeader)(ptr).Data == nil } func (type2 *UnsafeSliceType) SetNil(obj interface{}) { objEFace := unpackEFace(obj) assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype) type2.UnsafeSetNil(objEFace.data) } func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) { header := (*sliceHeader)(ptr) header.Len = 0 header.Cap = 0 header.Data = nil } func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} { return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap)) } func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer { header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap} return unsafe.Pointer(header) } func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int { objEFace := unpackEFace(obj) assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeLengthOf(objEFace.data) } func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int { header := (*sliceHeader)(obj) return header.Len } func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) { objEFace := unpackEFace(obj) assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype) elemEFace := unpackEFace(elem) assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype) type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data) } func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) { header := (*sliceHeader)(obj) elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len") typedmemmove(type2.elemRType, elemPtr, elem) } func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} { objEFace := unpackEFace(obj) assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype) elemPtr := type2.UnsafeGetIndex(objEFace.data, index) return packEFace(type2.pElemRType, elemPtr) } func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer { header := (*sliceHeader)(obj) return arrayAt(header.Data, index, type2.elemSize, "i < s.Len") } func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) { objEFace := unpackEFace(obj) assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype) elemEFace := unpackEFace(elem) assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype) type2.UnsafeAppend(objEFace.data, elemEFace.data) } func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) { header := (*sliceHeader)(obj) oldLen := header.Len type2.UnsafeGrow(obj, oldLen+1) type2.UnsafeSetIndex(obj, oldLen, elem) } func (type2 *UnsafeSliceType) Cap(obj interface{}) int { objEFace := unpackEFace(obj) assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeCap(objEFace.data) } func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int { return (*sliceHeader)(ptr).Cap } func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) { objEFace := unpackEFace(obj) assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype) type2.UnsafeGrow(objEFace.data, newLength) } func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) { header := (*sliceHeader)(obj) if newLength <= header.Cap { header.Len = newLength return } newCap := calcNewCap(header.Cap, newLength) newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap)) typedslicecopy(type2.elemRType, *newHeader, *header) header.Data = newHeader.Data header.Cap = newHeader.Cap header.Len = newLength } func calcNewCap(cap int, expectedCap int) int { if cap == 0 { cap = expectedCap } else { for cap < expectedCap { if cap < 1024 { cap += cap } else { cap += cap / 4 } } } return cap } golang-github-modern-go-reflect2-1.0.0/unsafe_struct.go000066400000000000000000000030011324545112400230370ustar00rootroot00000000000000package reflect2 import ( "reflect" "unsafe" ) type UnsafeStructType struct { unsafeType likePtr bool } func newUnsafeStructType(cfg *frozenConfig, type1 reflect.Type) *UnsafeStructType { return &UnsafeStructType{ unsafeType: *newUnsafeType(cfg, type1), likePtr: likePtrType(type1), } } func (type2 *UnsafeStructType) LikePtr() bool { return type2.likePtr } func (type2 *UnsafeStructType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *UnsafeStructType) UnsafeIndirect(ptr unsafe.Pointer) interface{} { if type2.likePtr { return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr)) } return packEFace(type2.rtype, ptr) } func (type2 *UnsafeStructType) FieldByName(name string) StructField { structField, found := type2.Type.FieldByName(name) if !found { return nil } return newUnsafeStructField(type2, structField) } func (type2 *UnsafeStructType) Field(i int) StructField { return newUnsafeStructField(type2, type2.Type.Field(i)) } func (type2 *UnsafeStructType) FieldByIndex(index []int) StructField { return newUnsafeStructField(type2, type2.Type.FieldByIndex(index)) } func (type2 *UnsafeStructType) FieldByNameFunc(match func(string) bool) StructField { structField, found := type2.Type.FieldByNameFunc(match) if !found { panic("field match condition not found in " + type2.Type.String()) } return newUnsafeStructField(type2, structField) }golang-github-modern-go-reflect2-1.0.0/unsafe_type.go000066400000000000000000000043161324545112400225060ustar00rootroot00000000000000package reflect2 import ( "unsafe" "reflect" ) type unsafeType struct { safeType rtype unsafe.Pointer ptrRType unsafe.Pointer } func newUnsafeType(cfg *frozenConfig, type1 reflect.Type) *unsafeType { return &unsafeType{ safeType: safeType{ Type: type1, cfg: cfg, }, rtype: unpackEFace(type1).data, ptrRType: unpackEFace(reflect.PtrTo(type1)).data, } } func (type2 *unsafeType) Set(obj interface{}, val interface{}) { objEFace := unpackEFace(obj) assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype) valEFace := unpackEFace(val) assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype) type2.UnsafeSet(objEFace.data, valEFace.data) } func (type2 *unsafeType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) { typedmemmove(type2.rtype, ptr, val) } func (type2 *unsafeType) IsNil(obj interface{}) bool { objEFace := unpackEFace(obj) assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIsNil(objEFace.data) } func (type2 *unsafeType) UnsafeIsNil(ptr unsafe.Pointer) bool { return ptr == nil } func (type2 *unsafeType) UnsafeNew() unsafe.Pointer { return unsafe_New(type2.rtype) } func (type2 *unsafeType) New() interface{} { return packEFace(type2.ptrRType, type2.UnsafeNew()) } func (type2 *unsafeType) PackEFace(ptr unsafe.Pointer) interface{} { return packEFace(type2.ptrRType, ptr) } func (type2 *unsafeType) RType() uintptr { return uintptr(type2.rtype) } func (type2 *unsafeType) Indirect(obj interface{}) interface{} { objEFace := unpackEFace(obj) assertType("Type.Indirect argument 1", type2.ptrRType, objEFace.rtype) return type2.UnsafeIndirect(objEFace.data) } func (type2 *unsafeType) UnsafeIndirect(obj unsafe.Pointer) interface{} { return packEFace(type2.rtype, obj) } func (type2 *unsafeType) LikePtr() bool { return false } func assertType(where string, expectRType unsafe.Pointer, actualRType unsafe.Pointer) { if expectRType != actualRType { expectType := reflect.TypeOf(0) (*iface)(unsafe.Pointer(&expectType)).data = expectRType actualType := reflect.TypeOf(0) (*iface)(unsafe.Pointer(&actualType)).data = actualRType panic(where + ": expect " + expectType.String() + ", actual " + actualType.String()) } }