pointer_reflect.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build purego appengine
  5. package impl
  6. import (
  7. "fmt"
  8. "reflect"
  9. )
  10. // offset represents the offset to a struct field, accessible from a pointer.
  11. // The offset is the field index into a struct.
  12. type offset []int
  13. // offsetOf returns a field offset for the struct field.
  14. func offsetOf(f reflect.StructField) offset {
  15. if len(f.Index) != 1 {
  16. panic("embedded structs are not supported")
  17. }
  18. return f.Index
  19. }
  20. // pointer is an abstract representation of a pointer to a struct or field.
  21. type pointer struct{ v reflect.Value }
  22. // pointerOfValue returns v as a pointer.
  23. func pointerOfValue(v reflect.Value) pointer {
  24. return pointer{v: v}
  25. }
  26. // pointerOfIface returns the pointer portion of an interface.
  27. func pointerOfIface(v interface{}) pointer {
  28. return pointer{v: reflect.ValueOf(v)}
  29. }
  30. // IsNil reports whether the pointer is nil.
  31. func (p pointer) IsNil() bool {
  32. return p.v.IsNil()
  33. }
  34. // Apply adds an offset to the pointer to derive a new pointer
  35. // to a specified field. The current pointer must be pointing at a struct.
  36. func (p pointer) Apply(f offset) pointer {
  37. // TODO: Handle unexported fields in an API that hides XXX fields?
  38. return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
  39. }
  40. // AsValueOf treats p as a pointer to an object of type t and returns the value.
  41. // It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
  42. func (p pointer) AsValueOf(t reflect.Type) reflect.Value {
  43. if got := p.v.Type().Elem(); got != t {
  44. panic(fmt.Sprintf("invalid type: got %v, want %v", got, t))
  45. }
  46. return p.v
  47. }
  48. // AsIfaceOf treats p as a pointer to an object of type t and returns the value.
  49. // It is equivalent to p.AsValueOf(t).Interface()
  50. func (p pointer) AsIfaceOf(t reflect.Type) interface{} {
  51. return p.AsValueOf(t).Interface()
  52. }