github.com/modern-go/reflect2@v1.0.2/safe_map.go (about) 1 package reflect2 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type safeMapType struct { 9 safeType 10 } 11 12 func (type2 *safeMapType) Key() Type { 13 return type2.safeType.cfg.Type2(type2.Type.Key()) 14 } 15 16 func (type2 *safeMapType) MakeMap(cap int) interface{} { 17 ptr := reflect.New(type2.Type) 18 ptr.Elem().Set(reflect.MakeMap(type2.Type)) 19 return ptr.Interface() 20 } 21 22 func (type2 *safeMapType) UnsafeMakeMap(cap int) unsafe.Pointer { 23 panic("does not support unsafe operation") 24 } 25 26 func (type2 *safeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) { 27 keyVal := reflect.ValueOf(key) 28 elemVal := reflect.ValueOf(elem) 29 val := reflect.ValueOf(obj) 30 val.Elem().SetMapIndex(keyVal.Elem(), elemVal.Elem()) 31 } 32 33 func (type2 *safeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) { 34 panic("does not support unsafe operation") 35 } 36 37 func (type2 *safeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) { 38 keyVal := reflect.ValueOf(key) 39 if key == nil { 40 keyVal = reflect.New(type2.Type.Key()).Elem() 41 } 42 val := reflect.ValueOf(obj).MapIndex(keyVal) 43 if !val.IsValid() { 44 return nil, false 45 } 46 return val.Interface(), true 47 } 48 49 func (type2 *safeMapType) GetIndex(obj interface{}, key interface{}) interface{} { 50 val := reflect.ValueOf(obj).Elem() 51 keyVal := reflect.ValueOf(key).Elem() 52 elemVal := val.MapIndex(keyVal) 53 if !elemVal.IsValid() { 54 ptr := reflect.New(reflect.PtrTo(val.Type().Elem())) 55 return ptr.Elem().Interface() 56 } 57 ptr := reflect.New(elemVal.Type()) 58 ptr.Elem().Set(elemVal) 59 return ptr.Interface() 60 } 61 62 func (type2 *safeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer { 63 panic("does not support unsafe operation") 64 } 65 66 func (type2 *safeMapType) Iterate(obj interface{}) MapIterator { 67 m := reflect.ValueOf(obj).Elem() 68 return &safeMapIterator{ 69 m: m, 70 keys: m.MapKeys(), 71 } 72 } 73 74 func (type2 *safeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator { 75 panic("does not support unsafe operation") 76 } 77 78 type safeMapIterator struct { 79 i int 80 m reflect.Value 81 keys []reflect.Value 82 } 83 84 func (iter *safeMapIterator) HasNext() bool { 85 return iter.i != len(iter.keys) 86 } 87 88 func (iter *safeMapIterator) Next() (interface{}, interface{}) { 89 key := iter.keys[iter.i] 90 elem := iter.m.MapIndex(key) 91 iter.i += 1 92 keyPtr := reflect.New(key.Type()) 93 keyPtr.Elem().Set(key) 94 elemPtr := reflect.New(elem.Type()) 95 elemPtr.Elem().Set(elem) 96 return keyPtr.Interface(), elemPtr.Interface() 97 } 98 99 func (iter *safeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) { 100 panic("does not support unsafe operation") 101 }