go-hep.org/x/hep@v0.38.1/groot/gen.rtree.go (about)

     1  // Copyright ©2018 The go-hep 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  
     5  //go:build ignore
     6  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  	"log"
    12  	"os"
    13  	"reflect"
    14  	"text/template"
    15  
    16  	"go-hep.org/x/hep/groot/internal/genroot"
    17  	"go-hep.org/x/hep/groot/root"
    18  )
    19  
    20  func main() {
    21  	genLeaves()
    22  	genRLeaves()
    23  }
    24  
    25  func genLeaves() {
    26  	fname := "./rtree/leaf_gen.go"
    27  	year := genroot.ExtractYear(fname)
    28  	f, err := os.Create(fname)
    29  	if err != nil {
    30  		log.Fatal(err)
    31  	}
    32  	defer f.Close()
    33  
    34  	genroot.GenImports(year, "rtree", f,
    35  		"fmt",
    36  		"reflect",
    37  		"strings",
    38  		"unsafe", // FIXME(sbinet): needed for signed/unsigned handling
    39  		"",
    40  		"go-hep.org/x/hep/groot/root",
    41  		"go-hep.org/x/hep/groot/rbase",
    42  		"go-hep.org/x/hep/groot/rbytes",
    43  		"go-hep.org/x/hep/groot/rdict",
    44  		"go-hep.org/x/hep/groot/rmeta",
    45  		"go-hep.org/x/hep/groot/rtypes",
    46  		"go-hep.org/x/hep/groot/rvers",
    47  	)
    48  
    49  	for i, typ := range []struct {
    50  		Name       string
    51  		Type       string
    52  		Kind       string
    53  		UKind      string
    54  		LenType    int
    55  		GoLenType  int
    56  		DoUnsigned bool
    57  		RFunc      string
    58  		RFuncArray string
    59  		ResizeFunc string
    60  		WFunc      string
    61  		WFuncArray string
    62  		RangeType  string
    63  		RRangeFunc string
    64  		WRangeFunc string
    65  		Count      bool
    66  
    67  		WithStreamerElement bool   // for TLeaf{F16,D32}
    68  		Meta                string // name of rmeta.Enum to use (for TLeaf{F16,D32})
    69  	}{
    70  		{
    71  			Name:       "LeafO",
    72  			Type:       "bool",
    73  			Kind:       "reflect.Bool",
    74  			LenType:    1,
    75  			GoLenType:  int(reflect.TypeOf(true).Size()),
    76  			RFunc:      "r.ReadBool()",
    77  			RFuncArray: "r.ReadArrayBool",
    78  			ResizeFunc: "rbytes.ResizeBool",
    79  			WFunc:      "w.WriteBool",
    80  			WFuncArray: "w.WriteArrayBool",
    81  		},
    82  		{
    83  			Name:       "LeafB",
    84  			Type:       "int8",
    85  			Kind:       "reflect.Int8",
    86  			UKind:      "reflect.Uint8",
    87  			LenType:    1,
    88  			GoLenType:  int(reflect.TypeOf(int8(0)).Size()),
    89  			DoUnsigned: true,
    90  			RFunc:      "r.ReadI8()",
    91  			RFuncArray: "r.ReadArrayI8",
    92  			ResizeFunc: "rbytes.ResizeI8",
    93  			WFunc:      "w.WriteI8",
    94  			WFuncArray: "w.WriteArrayI8",
    95  			Count:      true,
    96  		},
    97  		{
    98  			Name:       "LeafS",
    99  			Type:       "int16",
   100  			Kind:       "reflect.Int16",
   101  			UKind:      "reflect.Uint16",
   102  			LenType:    2,
   103  			GoLenType:  int(reflect.TypeOf(int16(0)).Size()),
   104  			DoUnsigned: true,
   105  			RFunc:      "r.ReadI16()",
   106  			RFuncArray: "r.ReadArrayI16",
   107  			ResizeFunc: "rbytes.ResizeI16",
   108  			WFunc:      "w.WriteI16",
   109  			WFuncArray: "w.WriteArrayI16",
   110  			Count:      true,
   111  		},
   112  		{
   113  			Name:       "LeafI",
   114  			Type:       "int32",
   115  			Kind:       "reflect.Int32",
   116  			UKind:      "reflect.Uint32",
   117  			LenType:    4,
   118  			GoLenType:  int(reflect.TypeOf(int32(0)).Size()),
   119  			DoUnsigned: true,
   120  			RFunc:      "r.ReadI32()",
   121  			RFuncArray: "r.ReadArrayI32",
   122  			ResizeFunc: "rbytes.ResizeI32",
   123  			WFunc:      "w.WriteI32",
   124  			WFuncArray: "w.WriteArrayI32",
   125  			Count:      true,
   126  		},
   127  		{
   128  			Name:       "LeafL",
   129  			Type:       "int64",
   130  			Kind:       "reflect.Int64",
   131  			UKind:      "reflect.Uint64",
   132  			LenType:    8,
   133  			GoLenType:  int(reflect.TypeOf(int64(0)).Size()),
   134  			DoUnsigned: true,
   135  			RFunc:      "r.ReadI64()",
   136  			RFuncArray: "r.ReadArrayI64",
   137  			ResizeFunc: "rbytes.ResizeI64",
   138  			WFunc:      "w.WriteI64",
   139  			WFuncArray: "w.WriteArrayI64",
   140  			Count:      true,
   141  		},
   142  		{
   143  			Name:       "LeafG",
   144  			Type:       "int64",
   145  			Kind:       "reflect.Int64",
   146  			UKind:      "reflect.Uint64",
   147  			LenType:    8,
   148  			GoLenType:  int(reflect.TypeOf(int64(0)).Size()),
   149  			DoUnsigned: true,
   150  			RFunc:      "r.ReadI64()",
   151  			RFuncArray: "r.ReadArrayI64",
   152  			ResizeFunc: "rbytes.ResizeI64",
   153  			WFunc:      "w.WriteI64",
   154  			WFuncArray: "w.WriteArrayI64",
   155  			Count:      true,
   156  		},
   157  		{
   158  			Name:       "LeafF",
   159  			Type:       "float32",
   160  			Kind:       "reflect.Float32",
   161  			LenType:    4,
   162  			GoLenType:  int(reflect.TypeOf(float32(0)).Size()),
   163  			RFunc:      "r.ReadF32()",
   164  			RFuncArray: "r.ReadArrayF32",
   165  			ResizeFunc: "rbytes.ResizeF32",
   166  			WFunc:      "w.WriteF32",
   167  			WFuncArray: "w.WriteArrayF32",
   168  		},
   169  		{
   170  			Name:       "LeafD",
   171  			Type:       "float64",
   172  			Kind:       "reflect.Float64",
   173  			LenType:    8,
   174  			GoLenType:  int(reflect.TypeOf(float64(0)).Size()),
   175  			RFunc:      "r.ReadF64()",
   176  			RFuncArray: "r.ReadArrayF64",
   177  			ResizeFunc: "rbytes.ResizeF64",
   178  			WFunc:      "w.WriteF64",
   179  			WFuncArray: "w.WriteArrayF64",
   180  		},
   181  		{
   182  			Name:                "LeafF16",
   183  			Type:                "root.Float16",
   184  			Kind:                "reflect.Float32",
   185  			LenType:             4,
   186  			GoLenType:           int(reflect.TypeOf(root.Float16(0)).Size()),
   187  			RFunc:               "r.ReadF16(leaf.elm)",
   188  			RFuncArray:          "r.ReadArrayF16",
   189  			ResizeFunc:          "rbytes.ResizeF16",
   190  			WFunc:               "w.WriteF16",
   191  			WFuncArray:          "w.WriteArrayF16",
   192  			WithStreamerElement: true,
   193  			Meta:                "rmeta.Float16",
   194  		},
   195  		{
   196  			Name:                "LeafD32",
   197  			Type:                "root.Double32",
   198  			Kind:                "reflect.Float64",
   199  			LenType:             8,
   200  			GoLenType:           int(reflect.TypeOf(root.Double32(0)).Size()),
   201  			RFunc:               "r.ReadD32(leaf.elm)",
   202  			RFuncArray:          "r.ReadArrayD32",
   203  			ResizeFunc:          "rbytes.ResizeD32",
   204  			WFunc:               "w.WriteD32",
   205  			WFuncArray:          "w.WriteArrayD32",
   206  			WithStreamerElement: true,
   207  			Meta:                "rmeta.Double32",
   208  		},
   209  		{
   210  			Name:       "LeafC",
   211  			Type:       "string",
   212  			Kind:       "reflect.String",
   213  			LenType:    1,
   214  			GoLenType:  int(reflect.TypeOf("").Size()),
   215  			RFunc:      "r.ReadString()",
   216  			RFuncArray: "r.ReadArrayString",
   217  			ResizeFunc: "rbytes.ResizeStr",
   218  			WFunc:      "w.WriteString",
   219  			WFuncArray: "w.WriteArrayString",
   220  			RangeType:  "int32",
   221  			RRangeFunc: "r.ReadI32()",
   222  			WRangeFunc: "w.WriteI32",
   223  		},
   224  	} {
   225  		if i > 0 {
   226  			fmt.Fprintf(f, "\n")
   227  		}
   228  		if typ.RangeType == "" {
   229  			typ.RangeType = typ.Type
   230  			typ.RRangeFunc = typ.RFunc
   231  			typ.WRangeFunc = typ.WFunc
   232  		}
   233  		tmpl := template.Must(template.New(typ.Name).Parse(leafTmpl))
   234  		err = tmpl.Execute(f, typ)
   235  		if err != nil {
   236  			log.Fatalf("error executing template for %q: %v\n", typ.Name, err)
   237  		}
   238  	}
   239  
   240  	err = f.Close()
   241  	if err != nil {
   242  		log.Fatal(err)
   243  	}
   244  	genroot.GoFmt(f)
   245  }
   246  
   247  const leafTmpl = `// {{.Name}} implements ROOT T{{.Name}}
   248  type {{.Name}} struct {
   249  	rvers int16
   250  	tleaf
   251  	ptr *{{.Type}}
   252  	sli *[]{{.Type}}
   253  	min {{.RangeType}}
   254  	max {{.RangeType}}
   255  {{- if .WithStreamerElement}}
   256  	elm rbytes.StreamerElement
   257  {{- end}}
   258  }
   259  
   260  {{- if .WithStreamerElement}}
   261  func new{{.Name}}(b Branch, name string, shape []int, unsigned bool, count Leaf, elm rbytes.StreamerElement) *{{.Name}} {
   262  	const etype = {{.LenType}}
   263  	var lcnt leafCount
   264  	if count != nil {
   265  		lcnt = count.(leafCount)
   266  	}
   267  	return &{{.Name}}{
   268  		rvers: rvers.{{.Name}},
   269  		tleaf: newLeaf(name, shape, etype, 0, false, unsigned, lcnt, b),
   270  		elm:   elm,
   271  	}
   272  }
   273  {{- else}}
   274  func new{{.Name}}(b Branch, name string, shape []int, unsigned bool, count Leaf) *{{.Name}} {
   275  	const etype = {{.LenType}}
   276  	var lcnt leafCount
   277  	if count != nil {
   278  		lcnt = count.(leafCount)
   279  	}
   280  	return &{{.Name}}{
   281  		rvers: rvers.{{.Name}},
   282  		tleaf: newLeaf(name, shape, etype, 0, false, unsigned, lcnt, b),
   283  	}
   284  }
   285  {{- end}}
   286  
   287  // Class returns the ROOT class name.
   288  func (leaf *{{.Name}}) Class() string {
   289  	return "T{{.Name}}"
   290  }
   291  
   292  // Minimum returns the minimum value of the leaf.
   293  func (leaf *{{.Name}}) Minimum() {{.RangeType}} {
   294  	return leaf.min
   295  }
   296  
   297  // Maximum returns the maximum value of the leaf.
   298  func (leaf *{{.Name}}) Maximum() {{.RangeType}} {
   299  	return leaf.max
   300  }
   301  
   302  // Kind returns the leaf's kind.
   303  func (leaf *{{.Name}}) Kind() reflect.Kind {
   304  {{- if .DoUnsigned}}
   305  	if leaf.IsUnsigned() {
   306  		return {{.UKind}}
   307  	}
   308  	return {{.Kind}}
   309  {{- else}}
   310  	return {{.Kind}}
   311  {{- end}}
   312  }
   313  
   314  // Type returns the leaf's type.
   315  func (leaf *{{.Name}}) Type() reflect.Type {
   316  {{- if .DoUnsigned}}
   317  	if leaf.IsUnsigned() {
   318  		var v u{{.Type}}
   319  		return reflect.TypeOf(v)
   320  	}
   321  	var v {{.Type}}
   322  	return reflect.TypeOf(v)
   323  {{- else}}
   324  	var v {{.Type}}
   325  	return reflect.TypeOf(v)
   326  {{- end}}
   327  }
   328  
   329  {{- if .Count}}
   330  // ivalue returns the first leaf value as int
   331  func (leaf *{{.Name}}) ivalue() int {
   332  	return int(*leaf.ptr)
   333  }
   334  
   335  // imax returns the leaf maximum value as int
   336  func (leaf *{{.Name}}) imax() int {
   337  	return int(leaf.max)
   338  }
   339  {{- end}}
   340  
   341  func (leaf *{{.Name}}) TypeName() string {
   342  {{- if .DoUnsigned}}
   343  	if leaf.IsUnsigned() {
   344  		return "u{{.Type}}"
   345  	}
   346  	return "{{.Type}}"
   347  {{- else}}
   348  	return "{{.Type}}"
   349  {{- end}}
   350  }
   351  
   352  func (leaf *{{.Name}}) MarshalROOT(w *rbytes.WBuffer) (int, error) {
   353  	if w.Err() != nil {
   354  		return 0, w.Err()
   355  	}
   356  
   357  	hdr := w.WriteHeader(leaf.Class(), leaf.rvers)
   358  	w.WriteObject(&leaf.tleaf)
   359  {{- if .WithStreamerElement}}
   360  	{{.WRangeFunc}}(leaf.min, leaf.elm)
   361  	{{.WRangeFunc}}(leaf.max, leaf.elm)
   362  {{- else}}
   363  	{{.WRangeFunc}}(leaf.min)
   364  	{{.WRangeFunc}}(leaf.max)
   365  {{- end}}
   366  
   367  	return w.SetHeader(hdr)
   368  }
   369  
   370  func (leaf *{{.Name}}) UnmarshalROOT(r *rbytes.RBuffer) error {
   371  	if r.Err() != nil {
   372  		return r.Err()
   373  	}
   374  
   375  	hdr := r.ReadHeader(leaf.Class(), leaf.RVersion())
   376  	leaf.rvers = hdr.Vers
   377  
   378  	r.ReadObject(&leaf.tleaf)
   379  
   380  	leaf.min = {{.RRangeFunc}}
   381  	leaf.max = {{.RRangeFunc}}
   382  
   383  {{if .WithStreamerElement}}
   384  	if strings.Contains(leaf.Title(), "[") {
   385  		elm := rdict.Element{
   386  			Name:   *rbase.NewNamed(fmt.Sprintf("%s_Element", leaf.Name()), leaf.Title()),
   387  			Offset: 0,
   388  			Type:   {{.Meta}},
   389  		}.New()
   390  		leaf.elm = &elm
   391  	}
   392  {{- end}}
   393  
   394  	r.CheckHeader(hdr)
   395  	return r.Err()
   396  }
   397  
   398  func (leaf *{{.Name}}) readFromBuffer(r *rbytes.RBuffer) error {
   399  	if r.Err() != nil {
   400  		return r.Err()
   401  	}
   402  
   403  	if leaf.count == nil && leaf.ptr != nil {
   404  		*leaf.ptr = {{.RFunc}}
   405  	} else {
   406              if leaf.count != nil {
   407                  n := leaf.count.ivalue()
   408                  max := leaf.count.imax()
   409                  if n > max {
   410                          n = max
   411                  }
   412  				nn := leaf.tleaf.len * n
   413  				*leaf.sli = {{.ResizeFunc}}(*leaf.sli, nn)
   414  {{- if .WithStreamerElement}}
   415                  {{.RFuncArray}}(*leaf.sli, leaf.elm)
   416  {{- else}}
   417                  {{.RFuncArray}}(*leaf.sli)
   418  {{- end}}
   419              } else {
   420  				nn := leaf.tleaf.len
   421  				*leaf.sli = {{.ResizeFunc}}(*leaf.sli, nn)
   422  {{- if .WithStreamerElement}}
   423  				{{.RFuncArray}}(*leaf.sli, leaf.elm)
   424  {{- else}}
   425  				{{.RFuncArray}}(*leaf.sli)
   426  {{- end}}
   427              }
   428      }
   429      return r.Err()
   430  }
   431  
   432  func (leaf *{{.Name}}) unsafeDecayArray(ptr any) any {
   433  	rv := reflect.ValueOf(ptr).Elem()
   434  	sz := rv.Type().Size() / {{.GoLenType}}
   435  	sli := unsafe.Slice((*{{.Type}})(unsafe.Pointer(rv.UnsafeAddr())), sz)
   436  	return &sli
   437  }
   438  
   439  func (leaf *{{.Name}}) setAddress(ptr any) error {
   440  	if ptr == nil {
   441  		return leaf.setAddress(newValue(leaf))
   442  	}
   443  
   444      if rv := reflect.Indirect(reflect.ValueOf(ptr)); rv.Kind() == reflect.Array {
   445  		sli := leaf.unsafeDecayArray(ptr)
   446  		switch sli := sli.(type) {
   447  		case *[]{{.Type}}:
   448  			return leaf.setAddress(sli)
   449  {{- if .DoUnsigned}}
   450  		case *[]u{{.Type}}:
   451  			return leaf.setAddress(sli)
   452  {{- end}}
   453  		default:
   454  			panic(fmt.Errorf("invalid ptr type %T (leaf=%s|%T)", ptr, leaf.Name(), leaf))
   455  		}
   456      }
   457  
   458  	switch v := ptr.(type) {
   459      case *{{.Type}}:
   460  		leaf.ptr = v
   461      case *[]{{.Type}}:
   462  		leaf.sli = v
   463  		if *v == nil {
   464  			*leaf.sli = make([]{{.Type}}, 0)
   465  		}
   466  {{- if .DoUnsigned}}
   467      case *u{{.Type}}:
   468  		leaf.ptr = (*{{.Type}})(unsafe.Pointer(v))
   469      case *[]u{{.Type}}:
   470  		leaf.sli = (*[]{{.Type}})(unsafe.Pointer(v))
   471  		if *v == nil {
   472  			*leaf.sli = make([]{{.Type}}, 0)
   473  		}
   474  {{- end}}
   475  	default:
   476  		panic(fmt.Errorf("invalid ptr type %T (leaf=%s|%T)", v, leaf.Name(), leaf))
   477  	}
   478  	return nil
   479  }
   480  
   481  func (leaf *{{.Name}}) writeToBuffer(w *rbytes.WBuffer) (int, error) {
   482  	if w.Err() != nil {
   483  		return 0, w.Err()
   484  	}
   485  
   486  	var nbytes int
   487  	switch {
   488  	case leaf.ptr != nil:
   489  {{- if .WithStreamerElement}}
   490  		{{.WFunc}}(*leaf.ptr, leaf.elm)
   491  {{- else}}
   492  		{{.WFunc}}(*leaf.ptr)
   493  {{- end}}
   494  {{- if eq .Name "LeafC"}}
   495  		sz := len(*leaf.ptr)
   496  		nbytes += sz
   497  		if v := int32(sz); v >= leaf.max {
   498  			leaf.max = v+1
   499  		}
   500  		if sz >= leaf.tleaf.len {
   501  			leaf.tleaf.len = sz+1
   502  		}
   503  {{- else if eq .Name "LeafO"}}
   504  		nbytes += leaf.tleaf.etype
   505  {{- else}}
   506  		nbytes += leaf.tleaf.etype
   507  		if v := *leaf.ptr; v > leaf.max {
   508  			leaf.max = v
   509  		}
   510  {{- end}}
   511  	case leaf.count != nil:
   512  		n := leaf.count.ivalue()
   513          max := leaf.count.imax()
   514          if n > max {
   515  			n = max
   516  		}
   517  		end := leaf.tleaf.len*n
   518  {{- if .WithStreamerElement}}
   519  		{{.WFuncArray}}((*leaf.sli)[:end], leaf.elm)
   520  {{- else}}
   521  		{{.WFuncArray}}((*leaf.sli)[:end])
   522  {{- end}}
   523  		nbytes += leaf.tleaf.etype * end
   524  	default:
   525  {{- if .WithStreamerElement}}
   526  		{{.WFuncArray}}((*leaf.sli)[:leaf.tleaf.len], leaf.elm)
   527  {{- else}}
   528  		{{.WFuncArray}}((*leaf.sli)[:leaf.tleaf.len])
   529  {{- end}}
   530  		nbytes += leaf.tleaf.etype * leaf.tleaf.len
   531  	}
   532  
   533  	return nbytes, w.Err()
   534  }
   535  
   536  func init() {
   537  	f := func() reflect.Value {
   538  		o := &{{.Name}}{}
   539  		return reflect.ValueOf(o)
   540  	}
   541  	rtypes.Factory.Add("T{{.Name}}", f)
   542  }
   543  
   544  var (
   545  	_ root.Object        = (*{{.Name}})(nil)
   546  	_ root.Named         = (*{{.Name}})(nil)
   547  	_ Leaf               = (*{{.Name}})(nil)
   548  	_ rbytes.Marshaler   = (*{{.Name}})(nil)
   549  	_ rbytes.Unmarshaler = (*{{.Name}})(nil)
   550  )
   551  `
   552  
   553  func genRLeaves() {
   554  	fname := "./rtree/rleaf_gen.go"
   555  	year := genroot.ExtractYear(fname)
   556  	f, err := os.Create(fname)
   557  	if err != nil {
   558  		log.Fatal(err)
   559  	}
   560  	defer f.Close()
   561  
   562  	type Kind string
   563  	const (
   564  		Val = Kind("Val")
   565  		Arr = Kind("Arr")
   566  		Sli = Kind("Sli")
   567  	)
   568  
   569  	genroot.GenImports(year, "rtree", f,
   570  		"reflect",
   571  		"unsafe", // for unsafeDecayArrayXXX
   572  		"",
   573  		"go-hep.org/x/hep/groot/rbytes",
   574  		"go-hep.org/x/hep/groot/root",
   575  	)
   576  
   577  	for i, typ := range []struct {
   578  		Name  string
   579  		Base  string
   580  		Type  string
   581  		Size  int
   582  		Kind  Kind
   583  		Func  string
   584  		Count bool
   585  
   586  		WithStreamerElement bool // for TLeaf{F16,D32}
   587  	}{
   588  		{
   589  			Name: "Bool",
   590  			Base: "LeafO",
   591  			Type: "bool",
   592  			Size: int(reflect.TypeOf(true).Size()),
   593  		},
   594  		{
   595  			Name:  "I8",
   596  			Base:  "LeafB",
   597  			Type:  "int8",
   598  			Size:  int(reflect.TypeOf(int8(0)).Size()),
   599  			Count: true,
   600  		},
   601  		{
   602  			Name:  "I16",
   603  			Base:  "LeafS",
   604  			Type:  "int16",
   605  			Size:  int(reflect.TypeOf(int16(0)).Size()),
   606  			Count: true,
   607  		},
   608  		{
   609  			Name:  "I32",
   610  			Base:  "LeafI",
   611  			Type:  "int32",
   612  			Size:  int(reflect.TypeOf(int32(0)).Size()),
   613  			Count: true,
   614  		},
   615  		{
   616  			Name:  "I64",
   617  			Base:  "LeafL",
   618  			Type:  "int64",
   619  			Size:  int(reflect.TypeOf(int64(0)).Size()),
   620  			Count: true,
   621  		},
   622  		{
   623  			Name:  "U8",
   624  			Base:  "LeafB",
   625  			Type:  "uint8",
   626  			Size:  int(reflect.TypeOf(uint8(0)).Size()),
   627  			Count: true,
   628  		},
   629  		{
   630  			Name:  "U16",
   631  			Base:  "LeafS",
   632  			Type:  "uint16",
   633  			Size:  int(reflect.TypeOf(uint16(0)).Size()),
   634  			Count: true,
   635  		},
   636  		{
   637  			Name:  "U32",
   638  			Base:  "LeafI",
   639  			Type:  "uint32",
   640  			Size:  int(reflect.TypeOf(uint32(0)).Size()),
   641  			Count: true,
   642  		},
   643  		{
   644  			Name:  "U64",
   645  			Base:  "LeafL",
   646  			Type:  "uint64",
   647  			Size:  int(reflect.TypeOf(uint64(0)).Size()),
   648  			Count: true,
   649  		},
   650  		{
   651  			Name: "F32",
   652  			Base: "LeafF",
   653  			Type: "float32",
   654  			Size: int(reflect.TypeOf(float32(0)).Size()),
   655  		},
   656  		{
   657  			Name: "F64",
   658  			Base: "LeafD",
   659  			Type: "float64",
   660  			Size: int(reflect.TypeOf(float64(0)).Size()),
   661  		},
   662  		{
   663  			Name: "D32",
   664  			Base: "LeafD32",
   665  			Type: "root.Double32",
   666  			Size: int(reflect.TypeOf(root.Double32(0)).Size()),
   667  
   668  			WithStreamerElement: true,
   669  		},
   670  		{
   671  			Name: "F16",
   672  			Base: "LeafF16",
   673  			Type: "root.Float16",
   674  			Size: int(reflect.TypeOf(root.Float16(0)).Size()),
   675  
   676  			WithStreamerElement: true,
   677  		},
   678  		{
   679  			Name: "Str",
   680  			Base: "LeafC",
   681  			Type: "string",
   682  			Size: int(reflect.TypeOf("").Size()),
   683  		},
   684  	} {
   685  		for j, kind := range []Kind{Val, Arr, Sli} {
   686  			if i > 0 || j > 0 {
   687  				fmt.Fprintf(f, "\n")
   688  			}
   689  			typ.Kind = kind
   690  			switch typ.Name {
   691  			case "Str":
   692  				typ.Func = "String"
   693  			default:
   694  				typ.Func = typ.Name
   695  			}
   696  
   697  			tmpl := template.Must(template.New(typ.Name).Parse(rleafTmpl))
   698  			err = tmpl.Execute(f, typ)
   699  			if err != nil {
   700  				log.Fatalf("error executing template for %q: %v\n", typ.Name, err)
   701  			}
   702  		}
   703  	}
   704  
   705  	err = f.Close()
   706  	if err != nil {
   707  		log.Fatal(err)
   708  	}
   709  	genroot.GoFmt(f)
   710  }
   711  
   712  const rleafTmpl = `// rleaf{{.Kind}}{{.Name}} implements rleaf for ROOT T{{.Base}}
   713  type rleaf{{.Kind}}{{.Name}} struct {
   714  	base *{{.Base}}
   715  {{- if eq .Kind "Val" }}
   716  	v *{{.Type}}
   717  {{- else if eq .Kind "Arr" }}
   718  	v []{{.Type}}
   719  {{- else if eq .Kind "Sli" }}
   720  	n   func() int
   721  	v   *[]{{.Type}}
   722  	set func() // reslice underlying slice
   723  {{- end}}
   724  {{- if .WithStreamerElement}}
   725  	elm rbytes.StreamerElement
   726  {{- end}}
   727  }
   728  
   729  {{- if eq .Kind "Val"}}
   730  func newRLeaf{{.Name}}(leaf *{{.Base}}, rvar ReadVar, rctx rleafCtx) rleaf {
   731  	switch {
   732  	case leaf.count != nil:
   733  		switch len(leaf.Shape()) {
   734  		case 0:
   735  			slice := reflect.ValueOf(rvar.Value).Interface().(*[]{{.Type}})
   736  			if *slice == nil {
   737  				*slice = make([]{{.Type}}, 0, rleafDefaultSliceCap)
   738  			}
   739  			return &rleafSli{{.Name}}{
   740  				base: leaf,
   741  				n:    rctx.rcountFunc(leaf.count.Name()),
   742  				v:    slice,
   743  				set:  func() {},
   744  			}
   745  		default:
   746  			sz := 1
   747  			for _, v := range leaf.Shape() {
   748  				sz *= v
   749  			}
   750  			sli := reflect.ValueOf(rvar.Value).Elem()
   751  			ptr := (*[]{{.Type}})(unsafe.Pointer(sli.UnsafeAddr()))
   752  			hdr := unsafeDecaySliceArray[{{.Type}}](ptr, sz)
   753  			if *hdr == nil {
   754  				*hdr = make([]{{.Type}}, 0, rleafDefaultSliceCap*sz)
   755  			}
   756  			rleaf := &rleafSli{{.Name}}{
   757  				base: leaf,
   758  				n:    rctx.rcountFunc(leaf.count.Name()),
   759  				v:    hdr,
   760  			}
   761  			rhdr := reflect.ValueOf(hdr).Elem()
   762  			rptr := reflect.ValueOf(ptr).Elem()
   763  
   764  			// alias slices
   765  			rptr.Set(rhdr)
   766  
   767  			rleaf.set = func() {
   768  				n := rleaf.n()
   769  				rptr.SetLen(n)
   770  			}
   771  
   772  			return rleaf
   773  }
   774  
   775  	case leaf.len > 1:
   776  		return &rleafArr{{.Name}}{
   777  			base: leaf,
   778  			v:    *unsafeDecayArray[{{.Type}}](rvar.Value),
   779  		}
   780  
   781  	default:
   782  		return &rleafVal{{.Name}}{
   783  			base: leaf,
   784  			v:    reflect.ValueOf(rvar.Value).Interface().(*{{.Type}}),
   785  		}
   786  	}
   787  }
   788  {{- end}}
   789  
   790  func (leaf *rleaf{{.Kind}}{{.Name}}) Leaf() Leaf { return leaf.base }
   791  
   792  func (leaf *rleaf{{.Kind}}{{.Name}}) Offset() int64 {
   793  	return int64(leaf.base.Offset())
   794  }
   795  
   796  {{if eq .Kind "Val"}}
   797  {{if .Count}}
   798  func (leaf *rleaf{{.Kind}}{{.Name}}) ivalue() int { return int(*leaf.v) }
   799  {{- end}}
   800  {{- end}}
   801  
   802  {{if .WithStreamerElement}}
   803  func (leaf *rleaf{{.Kind}}{{.Name}}) readFromBuffer(r *rbytes.RBuffer) error {
   804  {{- if eq .Kind "Val" }}
   805  	*leaf.v = r.Read{{.Func}}(leaf.elm)
   806  {{- else if eq .Kind "Arr" }}
   807  	r.ReadArray{{.Func}}(leaf.v, leaf.elm)
   808  {{- else if eq .Kind "Sli" }}
   809  	n := leaf.base.tleaf.len * leaf.n()
   810  	sli := rbytes.Resize{{.Name}}(*leaf.v, n)
   811  	r.ReadArray{{.Func}}(sli, leaf.elm)
   812  	*leaf.v = sli
   813  	leaf.set()
   814  {{- end}}
   815  	return r.Err()
   816  }
   817  {{else}}
   818  func (leaf *rleaf{{.Kind}}{{.Name}}) readFromBuffer(r *rbytes.RBuffer) error {
   819  {{- if eq .Kind "Val" }}
   820  	*leaf.v = r.Read{{.Func}}()
   821  {{- else if eq .Kind "Arr" }}
   822  	r.ReadArray{{.Func}}(leaf.v)
   823  {{- else if eq .Kind "Sli" }}
   824  	n := leaf.base.tleaf.len * leaf.n()
   825  	sli := rbytes.Resize{{.Name}}(*leaf.v, n)
   826  	r.ReadArray{{.Func}}(sli)
   827  	*leaf.v = sli
   828  	leaf.set()
   829  {{- end}}
   830  	return r.Err()
   831  }
   832  {{- end}}
   833  
   834  var (
   835  	_ rleaf = (*rleaf{{.Kind}}{{.Name}})(nil)
   836  )
   837  `