def_move.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // package def_move -- параметрический контейнер с семантикой перемещения.
  2. package def_move
  3. import (
  4. "reflect"
  5. "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_spec_base"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/table/owner"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/d0/helpers"
  8. )
  9. // Move -- параметрический контейнер с семантикой перемещения
  10. type Move[T any] struct {
  11. owner *owner.LOwner
  12. val *T // Фактическое значение
  13. }
  14. const (
  15. str5 = def_spec_base.Txt("NewBox(): val==nil")
  16. )
  17. // NewMove -- возвращает новый параметрический контейнер с семантикой перемещения
  18. func NewMove[T any](owner *owner.LOwner, val T) *Move[T] {
  19. helpers.If(owner == nil).Hassert("NewMove[%T](): owner==nil", val)
  20. v := reflect.ValueOf(val)
  21. switch v.Kind() {
  22. case reflect.Pointer, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
  23. isNil := def_spec_base.Bool(v.IsNil())
  24. helpers.If(isNil).Hassert(str5)
  25. }
  26. sf := &Move[T]{
  27. owner: owner,
  28. val: &val,
  29. }
  30. return sf
  31. }
  32. // Set -- устанавливает внутреннее значение
  33. func (sf *Move[T]) Set(val T) {
  34. sf.owner.Pass().CheckOwner()
  35. v := reflect.ValueOf(val)
  36. switch v.Kind() {
  37. case reflect.Pointer, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func, reflect.Interface:
  38. isNil := def_spec_base.Bool(v.IsNil())
  39. helpers.If(isNil).Hassert(str5)
  40. }
  41. sf.val = &val
  42. }
  43. // Move -- перемещает другому владельцу хранимое значение
  44. func (sf *Move[T]) Move() T {
  45. sf.owner.Pass().CheckOwner()
  46. defer func() {
  47. sf.val = nil
  48. }()
  49. helpers.If(sf.val == nil).Hassert("Box.Move[%T]: val already moved", sf.val)
  50. return *sf.val
  51. }