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

     1  // Copyright ©2019 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  package rtree
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"testing"
    11  
    12  	"go-hep.org/x/hep/groot/rbase"
    13  	"go-hep.org/x/hep/groot/rbytes"
    14  	"go-hep.org/x/hep/groot/rdict"
    15  	"go-hep.org/x/hep/groot/rmeta"
    16  	"go-hep.org/x/hep/groot/root"
    17  )
    18  
    19  func TestLeafDims(t *testing.T) {
    20  	for _, tc := range []struct {
    21  		s    string
    22  		want []int
    23  	}{
    24  		{s: "Leaf", want: nil},
    25  		{s: "Leaf/F", want: nil},
    26  		{s: "Leaf[]", want: []int{-1}},
    27  		{s: "Leaf[]/F", want: []int{-1}},
    28  		{s: "Leaf[20]", want: []int{20}},
    29  		{s: "Leaf[20]/F", want: []int{20}},
    30  		{s: "Leaf[2000]", want: []int{2000}},
    31  		{s: "Leaf[1][2]", want: []int{1, 2}},
    32  		{s: "Leaf[2][]", want: []int{2, -1}},
    33  		{s: "Leaf[1][2][3]", want: []int{1, 2, 3}},
    34  		{s: "Leaf[1][2][3]/F", want: []int{1, 2, 3}},
    35  	} {
    36  		t.Run(tc.s, func(t *testing.T) {
    37  			dims := leafDims(tc.s)
    38  			if !reflect.DeepEqual(dims, tc.want) {
    39  				t.Fatalf("invalid dims. got=%#v, want=%#v", dims, tc.want)
    40  			}
    41  		})
    42  	}
    43  }
    44  
    45  func TestLeafReadWriteBasket(t *testing.T) {
    46  	const (
    47  		unsigned = true
    48  		signed   = false
    49  	)
    50  
    51  	var (
    52  		br   = new(testBranchImpl)
    53  		scnt = newLeafI(br, "N", nil, signed, nil)
    54  		ucnt = newLeafI(br, "N", nil, unsigned, nil)
    55  	)
    56  
    57  	for _, tc := range []struct {
    58  		leaf Leaf
    59  		lcnt Leaf
    60  		data any
    61  	}{
    62  		{
    63  			leaf: newLeafO(br, "BoolTrue", nil, signed, nil),
    64  			data: true,
    65  		},
    66  		{
    67  			leaf: newLeafO(br, "BoolFalse", nil, signed, nil),
    68  			data: false,
    69  		},
    70  		{
    71  			leaf: newLeafB(br, "I8", nil, signed, nil),
    72  			data: int8(-42),
    73  		},
    74  		{
    75  			leaf: newLeafS(br, "I16", nil, signed, nil),
    76  			data: int16(-42),
    77  		},
    78  		{
    79  			leaf: newLeafI(br, "I32", nil, signed, nil),
    80  			data: int32(-42),
    81  		},
    82  		{
    83  			leaf: newLeafL(br, "I64", nil, signed, nil),
    84  			data: int64(-42),
    85  		},
    86  		{
    87  			leaf: newLeafG(br, "G64", nil, signed, nil),
    88  			data: int64(-42),
    89  		},
    90  		{
    91  			leaf: newLeafB(br, "U8", nil, unsigned, nil),
    92  			data: uint8(42),
    93  		},
    94  		{
    95  			leaf: newLeafS(br, "U16", nil, unsigned, nil),
    96  			data: uint16(42),
    97  		},
    98  		{
    99  			leaf: newLeafI(br, "U32", nil, unsigned, nil),
   100  			data: uint32(42),
   101  		},
   102  		{
   103  			leaf: newLeafL(br, "U64", nil, unsigned, nil),
   104  			data: uint64(42),
   105  		},
   106  		{
   107  			leaf: newLeafG(br, "U64", nil, unsigned, nil),
   108  			data: uint64(42),
   109  		},
   110  		{
   111  			leaf: newLeafF(br, "F32", nil, signed, nil),
   112  			data: float32(42),
   113  		},
   114  		{
   115  			leaf: newLeafD(br, "F64", nil, signed, nil),
   116  			data: float64(42),
   117  		},
   118  		{
   119  			leaf: newLeafF16(br, "D16", nil, signed, nil, nil),
   120  			data: root.Float16(42),
   121  		},
   122  		{
   123  			leaf: newLeafF16(br, "D16Range", nil, signed, nil, func() rbytes.StreamerElement {
   124  				elm := rdict.Element{
   125  					Name: *rbase.NewNamed("D16Range", "D16Range/f[0, 42]"),
   126  					Type: rmeta.Float16,
   127  				}.New()
   128  				return &elm
   129  			}()),
   130  			data: root.Float16(42),
   131  		},
   132  		{
   133  			leaf: newLeafD32(br, "D32", nil, signed, nil, nil),
   134  			data: root.Double32(42),
   135  		},
   136  		{
   137  			leaf: newLeafD32(br, "D32Range", nil, signed, nil, func() rbytes.StreamerElement {
   138  				elm := rdict.Element{
   139  					Name: *rbase.NewNamed("D32Range", "D32Range/d[0, 42]"),
   140  					Type: rmeta.Double32,
   141  				}.New()
   142  				return &elm
   143  			}()),
   144  			data: root.Double32(42),
   145  		},
   146  		{
   147  			leaf: newLeafO(br, "ArrBools", []int{4}, signed, nil),
   148  			data: [4]bool{true, false, true, false},
   149  		},
   150  		{
   151  			leaf: newLeafB(br, "ArrI8", []int{4}, signed, nil),
   152  			data: [4]int8{1, 2, 3, 4},
   153  		},
   154  		{
   155  			leaf: newLeafS(br, "ArrI16", []int{4}, signed, nil),
   156  			data: [4]int16{1, 2, 3, 4},
   157  		},
   158  		{
   159  			leaf: newLeafI(br, "ArrI32", []int{4}, signed, nil),
   160  			data: [4]int32{1, 2, 3, 4},
   161  		},
   162  		{
   163  			leaf: newLeafL(br, "ArrI64", []int{4}, signed, nil),
   164  			data: [4]int64{1, 2, 3, 4},
   165  		},
   166  		{
   167  			leaf: newLeafG(br, "ArrG64", []int{4}, signed, nil),
   168  			data: [4]int64{1, 2, 3, 4},
   169  		},
   170  		{
   171  			leaf: newLeafB(br, "ArrU8", []int{4}, unsigned, nil),
   172  			data: [4]uint8{1, 2, 3, 4},
   173  		},
   174  		{
   175  			leaf: newLeafS(br, "ArrU16", []int{4}, unsigned, nil),
   176  			data: [4]uint16{1, 2, 3, 4},
   177  		},
   178  		{
   179  			leaf: newLeafI(br, "ArrU32", []int{4}, unsigned, nil),
   180  			data: [4]uint32{1, 2, 3, 4},
   181  		},
   182  		{
   183  			leaf: newLeafL(br, "ArrU64", []int{4}, unsigned, nil),
   184  			data: [4]uint64{1, 2, 3, 4},
   185  		},
   186  		{
   187  			leaf: newLeafG(br, "ArrU64", []int{4}, unsigned, nil),
   188  			data: [4]uint64{1, 2, 3, 4},
   189  		},
   190  		{
   191  			leaf: newLeafF(br, "ArrF32", []int{4}, signed, nil),
   192  			data: [4]float32{1, 2, 3, 4},
   193  		},
   194  		{
   195  			leaf: newLeafD(br, "ArrF64", []int{4}, signed, nil),
   196  			data: [4]float64{1, 2, 3, 4},
   197  		},
   198  		{
   199  			leaf: newLeafD32(br, "ArrD32", []int{4}, signed, nil, nil),
   200  			data: [4]root.Double32{1, 2, 3, 4},
   201  		},
   202  		{
   203  			leaf: newLeafD32(br, "ArrD32Range", []int{4}, signed, nil, func() rbytes.StreamerElement {
   204  				elm := rdict.Element{
   205  					Name: *rbase.NewNamed("ArrD32Range", "ArrD32Range[4]d/[0,4]"),
   206  					Type: rmeta.Double32,
   207  				}.New()
   208  				return &elm
   209  			}()),
   210  			data: [4]root.Double32{0, 4, 0, 4},
   211  		},
   212  		{
   213  			leaf: newLeafO(br, "SliBools", nil, signed, scnt),
   214  			data: []bool{true, false, true, false},
   215  			lcnt: newLeafI(br, "N", nil, signed, nil),
   216  		},
   217  		{
   218  			leaf: newLeafO(br, "SliUBools", nil, unsigned, ucnt),
   219  			data: []bool{true, false, true, false},
   220  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   221  		},
   222  		{
   223  			leaf: newLeafB(br, "SliI8", nil, signed, scnt),
   224  			data: []int8{1, 2, 3, 4},
   225  			lcnt: newLeafI(br, "N", nil, signed, nil),
   226  		},
   227  		{
   228  			leaf: newLeafS(br, "SliI16", nil, signed, scnt),
   229  			data: []int16{1, 2, 3, 4},
   230  			lcnt: newLeafI(br, "N", nil, signed, nil),
   231  		},
   232  		{
   233  			leaf: newLeafI(br, "SliI32", nil, signed, scnt),
   234  			data: []int32{1, 2, 3, 4},
   235  			lcnt: newLeafI(br, "N", nil, signed, nil),
   236  		},
   237  		{
   238  			leaf: newLeafL(br, "SliI64", nil, signed, scnt),
   239  			data: []int64{1, 2, 3, 4},
   240  			lcnt: newLeafI(br, "N", nil, signed, nil),
   241  		},
   242  		{
   243  			leaf: newLeafG(br, "SliG64", nil, signed, scnt),
   244  			data: []int64{1, 2, 3, 4},
   245  			lcnt: newLeafI(br, "N", nil, signed, nil),
   246  		},
   247  		{
   248  			leaf: newLeafB(br, "SliU8", nil, unsigned, ucnt),
   249  			data: []uint8{1, 2, 3, 4},
   250  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   251  		},
   252  		{
   253  			leaf: newLeafS(br, "SliU16", nil, unsigned, ucnt),
   254  			data: []uint16{1, 2, 3, 4},
   255  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   256  		},
   257  		{
   258  			leaf: newLeafI(br, "SliU32", nil, unsigned, ucnt),
   259  			data: []uint32{1, 2, 3, 4},
   260  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   261  		},
   262  		{
   263  			leaf: newLeafL(br, "SliU64", nil, unsigned, ucnt),
   264  			data: []uint64{1, 2, 3, 4},
   265  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   266  		},
   267  		{
   268  			leaf: newLeafG(br, "SliU64", nil, unsigned, ucnt),
   269  			data: []uint64{1, 2, 3, 4},
   270  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   271  		},
   272  		{
   273  			leaf: newLeafF(br, "SliF32", nil, unsigned, ucnt),
   274  			data: []float32{1, 2, 3, 4},
   275  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   276  		},
   277  		{
   278  			leaf: newLeafD(br, "SliF64", nil, unsigned, ucnt),
   279  			data: []float64{1, 2, 3, 4},
   280  			lcnt: newLeafI(br, "N", nil, unsigned, nil),
   281  		},
   282  	} {
   283  		t.Run(tc.leaf.Name(), func(t *testing.T) {
   284  			wbuf := rbytes.NewWBuffer(nil, nil, 0, nil)
   285  
   286  			if tc.lcnt != nil {
   287  				tc.leaf.(interface{ setLeafCount(leaf Leaf) }).setLeafCount(tc.lcnt)
   288  				wv := reflect.ValueOf(newValue(tc.lcnt))
   289  				switch {
   290  				case tc.lcnt.IsUnsigned():
   291  					wv.Elem().SetUint(uint64(reflect.ValueOf(tc.data).Len()))
   292  				default:
   293  					wv.Elem().SetInt(int64(reflect.ValueOf(tc.data).Len()))
   294  				}
   295  				err := tc.lcnt.setAddress(wv.Interface())
   296  				if err != nil {
   297  					t.Fatalf("could not setup leaf count: %v", err)
   298  				}
   299  
   300  				n, err := tc.lcnt.writeToBuffer(wbuf)
   301  				if err != nil {
   302  					t.Fatalf("could not write count to basket: %v", err)
   303  				}
   304  				if n == 0 {
   305  					t.Fatalf("short write")
   306  				}
   307  			}
   308  
   309  			wv := reflect.ValueOf(newValue(tc.leaf))
   310  			wv.Elem().Set(reflect.ValueOf(tc.data))
   311  
   312  			if got, want := wv.Elem().Interface(), tc.data; !reflect.DeepEqual(got, want) {
   313  				t.Fatalf("could not setup input data: got=%v, want=%v", got, want)
   314  			}
   315  
   316  			err := tc.leaf.setAddress(wv.Interface())
   317  			if err != nil {
   318  				t.Fatalf("could not set write-address: %v", err)
   319  			}
   320  
   321  			n, err := tc.leaf.writeToBuffer(wbuf)
   322  			if err != nil {
   323  				t.Fatalf("could not write to basket: %v", err)
   324  			}
   325  			if n == 0 {
   326  				t.Fatalf("short write")
   327  			}
   328  
   329  			rbuf := rbytes.NewRBuffer(wbuf.Bytes(), nil, 0, nil)
   330  
   331  			if tc.lcnt != nil {
   332  				tc.leaf.(interface{ setLeafCount(leaf Leaf) }).setLeafCount(tc.lcnt)
   333  				rv := reflect.ValueOf(newValue(tc.lcnt))
   334  				err := tc.lcnt.setAddress(rv.Interface())
   335  				if err != nil {
   336  					t.Fatalf("could not setup read leaf count: %v", err)
   337  				}
   338  
   339  				err = tc.lcnt.readFromBuffer(rbuf)
   340  				if err != nil {
   341  					t.Fatalf("could not write count to basket: %v", err)
   342  				}
   343  
   344  				dlen := reflect.ValueOf(tc.data).Len()
   345  				switch {
   346  				case tc.lcnt.IsUnsigned():
   347  					if got, want := int(rv.Elem().Uint()), dlen; got != want {
   348  						t.Fatalf("invalid r/w cycle leaf-count: got=%d, want=%d", got, want)
   349  					}
   350  				default:
   351  					if got, want := int(rv.Elem().Int()), dlen; got != want {
   352  						t.Fatalf("invalid r/w cycle leaf-count: got=%d, want=%d", got, want)
   353  					}
   354  				}
   355  			}
   356  
   357  			rv := reflect.ValueOf(newValue(tc.leaf))
   358  			err = tc.leaf.setAddress(rv.Interface())
   359  			if err != nil {
   360  				t.Fatalf("could not set read-address: %v", err)
   361  			}
   362  
   363  			err = tc.leaf.readFromBuffer(rbuf)
   364  			if err != nil {
   365  				t.Fatalf("could not read from basket: %v", err)
   366  			}
   367  
   368  			if got, want := rv.Elem().Interface(), wv.Elem().Interface(); !reflect.DeepEqual(got, want) {
   369  				t.Fatalf("invalid r/w cycle:\ngot= %v\nwant=%v", got, want)
   370  			}
   371  		})
   372  	}
   373  }
   374  
   375  func (leaf *LeafO) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   376  func (leaf *LeafB) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   377  func (leaf *LeafS) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   378  func (leaf *LeafI) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   379  func (leaf *LeafL) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   380  func (leaf *LeafG) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   381  func (leaf *LeafF) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   382  func (leaf *LeafD) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   383  func (leaf *LeafD32) setLeafCount(lcnt Leaf) { leaf.tleaf.count = lcnt.(leafCount) }
   384  func (leaf *LeafC) setLeafCount(lcnt Leaf)   { leaf.tleaf.count = lcnt.(leafCount) }
   385  
   386  type testBranchImpl struct {
   387  	tbranch
   388  }
   389  
   390  func (b *testBranchImpl) getReadEntry() int64 { return 1 }
   391  
   392  func TestAsLeafBase(t *testing.T) {
   393  	for _, tc := range []struct {
   394  		leaf Leaf
   395  		want rmeta.Enum
   396  	}{
   397  		{
   398  			leaf: new(LeafO),
   399  			want: rmeta.Bool,
   400  		},
   401  		{
   402  			leaf: new(LeafB),
   403  			want: rmeta.Int8,
   404  		},
   405  		{
   406  			leaf: new(LeafS),
   407  			want: rmeta.Int16,
   408  		},
   409  		{
   410  			leaf: new(LeafI),
   411  			want: rmeta.Int32,
   412  		},
   413  		{
   414  			leaf: new(LeafL),
   415  			want: rmeta.Int64,
   416  		},
   417  		{
   418  			leaf: new(LeafF),
   419  			want: rmeta.Float32,
   420  		},
   421  		{
   422  			leaf: new(LeafD),
   423  			want: rmeta.Float64,
   424  		},
   425  		{
   426  			leaf: new(LeafF16),
   427  			want: rmeta.Float16,
   428  		},
   429  		{
   430  			leaf: new(LeafD32),
   431  			want: rmeta.Double32,
   432  		},
   433  		{
   434  			leaf: new(LeafC),
   435  			want: rmeta.CharStar, // FIXME(sbinet): rmeta.Char?
   436  		},
   437  	} {
   438  		t.Run(fmt.Sprintf("%T", tc.leaf), func(t *testing.T) {
   439  			_, got := asLeafBase(tc.leaf)
   440  			if got != tc.want {
   441  				t.Fatalf("got=%v, want=%v", got, tc.want)
   442  			}
   443  		})
   444  	}
   445  }
   446  
   447  func TestLeafAPI(t *testing.T) {
   448  	var (
   449  		b        Branch
   450  		count    leafCount
   451  		shape    = []int{2, 3, 4, 5}
   452  		unsigned = true
   453  		signed   = false
   454  		norange  = false
   455  	)
   456  
   457  	for _, tc := range []struct {
   458  		leaf     Leaf
   459  		dims     []int
   460  		hasrange bool
   461  		unsigned bool
   462  		lentype  int
   463  		offset   int
   464  		kind     reflect.Kind
   465  		typ      reflect.Type
   466  		class    string
   467  		typename string
   468  		ptrs     []any
   469  	}{
   470  		{
   471  			leaf:     newLeafO(b, "leaf", shape, unsigned, count),
   472  			dims:     shape,
   473  			hasrange: norange,
   474  			unsigned: unsigned,
   475  			lentype:  1,
   476  			offset:   0,
   477  			kind:     reflect.TypeOf(false).Kind(),
   478  			typ:      reflect.TypeOf(false),
   479  			class:    "TLeafO",
   480  			typename: "bool",
   481  			ptrs: []any{
   482  				new(bool),
   483  				&[]bool{},
   484  				&[1][2][3][4][5]bool{},
   485  			},
   486  		},
   487  		{
   488  			leaf:     newLeafB(b, "leaf", shape, unsigned, count),
   489  			dims:     shape,
   490  			hasrange: norange,
   491  			unsigned: unsigned,
   492  			lentype:  1,
   493  			offset:   0,
   494  			kind:     reflect.TypeOf(uint8(0)).Kind(),
   495  			typ:      reflect.TypeOf(uint8(0)),
   496  			class:    "TLeafB",
   497  			typename: "uint8",
   498  			ptrs: []any{
   499  				new(int8),
   500  				&[]int8{},
   501  				&[1][2][3][4][5]int8{},
   502  				new(uint8),
   503  				&[]uint8{},
   504  				&[1][2][3][4][5]uint8{},
   505  			},
   506  		},
   507  		{
   508  			leaf:     newLeafB(b, "leaf", shape, signed, count),
   509  			dims:     shape,
   510  			hasrange: norange,
   511  			unsigned: signed,
   512  			lentype:  1,
   513  			offset:   0,
   514  			kind:     reflect.TypeOf(int8(0)).Kind(),
   515  			typ:      reflect.TypeOf(int8(0)),
   516  			class:    "TLeafB",
   517  			typename: "int8",
   518  			ptrs: []any{
   519  				new(int8),
   520  				&[]int8{},
   521  				&[1][2][3][4][5]int8{},
   522  				new(uint8),
   523  				&[]uint8{},
   524  				&[1][2][3][4][5]uint8{},
   525  			},
   526  		},
   527  		{
   528  			leaf:     newLeafS(b, "leaf", shape, unsigned, count),
   529  			dims:     shape,
   530  			hasrange: norange,
   531  			unsigned: unsigned,
   532  			lentype:  2,
   533  			offset:   0,
   534  			kind:     reflect.TypeOf(uint16(0)).Kind(),
   535  			typ:      reflect.TypeOf(uint16(0)),
   536  			class:    "TLeafS",
   537  			typename: "uint16",
   538  			ptrs: []any{
   539  				new(int16),
   540  				&[]int16{},
   541  				&[1][2][3][4][5]int16{},
   542  				new(uint16),
   543  				&[]uint16{},
   544  				&[1][2][3][4][5]uint16{},
   545  			},
   546  		},
   547  		{
   548  			leaf:     newLeafS(b, "leaf", shape, signed, count),
   549  			dims:     shape,
   550  			hasrange: norange,
   551  			unsigned: signed,
   552  			lentype:  2,
   553  			offset:   0,
   554  			kind:     reflect.TypeOf(int16(0)).Kind(),
   555  			typ:      reflect.TypeOf(int16(0)),
   556  			class:    "TLeafS",
   557  			typename: "int16",
   558  			ptrs: []any{
   559  				new(int16),
   560  				&[]int16{},
   561  				&[1][2][3][4][5]int16{},
   562  				new(uint16),
   563  				&[]uint16{},
   564  				&[1][2][3][4][5]uint16{},
   565  			},
   566  		},
   567  		{
   568  			leaf:     newLeafI(b, "leaf", shape, unsigned, count),
   569  			dims:     shape,
   570  			hasrange: norange,
   571  			unsigned: unsigned,
   572  			lentype:  4,
   573  			offset:   0,
   574  			kind:     reflect.TypeOf(uint32(0)).Kind(),
   575  			typ:      reflect.TypeOf(uint32(0)),
   576  			class:    "TLeafI",
   577  			typename: "uint32",
   578  			ptrs: []any{
   579  				new(int32),
   580  				&[]int32{},
   581  				&[1][2][3][4][5]int32{},
   582  				new(uint32),
   583  				&[]uint32{},
   584  				&[1][2][3][4][5]uint32{},
   585  			},
   586  		},
   587  		{
   588  			leaf:     newLeafI(b, "leaf", shape, signed, count),
   589  			dims:     shape,
   590  			hasrange: norange,
   591  			unsigned: signed,
   592  			lentype:  4,
   593  			offset:   0,
   594  			kind:     reflect.TypeOf(int32(0)).Kind(),
   595  			typ:      reflect.TypeOf(int32(0)),
   596  			class:    "TLeafI",
   597  			typename: "int32",
   598  			ptrs: []any{
   599  				new(int32),
   600  				&[]int32{},
   601  				&[1][2][3][4][5]int32{},
   602  				new(uint32),
   603  				&[]uint32{},
   604  				&[1][2][3][4][5]uint32{},
   605  			},
   606  		},
   607  		{
   608  			leaf:     newLeafL(b, "leaf", shape, unsigned, count),
   609  			dims:     shape,
   610  			hasrange: norange,
   611  			unsigned: unsigned,
   612  			lentype:  8,
   613  			offset:   0,
   614  			kind:     reflect.TypeOf(uint64(0)).Kind(),
   615  			typ:      reflect.TypeOf(uint64(0)),
   616  			class:    "TLeafL",
   617  			typename: "uint64",
   618  			ptrs: []any{
   619  				new(int64),
   620  				&[]int64{},
   621  				&[1][2][3][4][5]int64{},
   622  				new(uint64),
   623  				&[]uint64{},
   624  				&[1][2][3][4][5]uint64{},
   625  			},
   626  		},
   627  		{
   628  			leaf:     newLeafL(b, "leaf", shape, signed, count),
   629  			dims:     shape,
   630  			hasrange: norange,
   631  			unsigned: signed,
   632  			lentype:  8,
   633  			offset:   0,
   634  			kind:     reflect.TypeOf(int64(0)).Kind(),
   635  			typ:      reflect.TypeOf(int64(0)),
   636  			class:    "TLeafL",
   637  			typename: "int64",
   638  			ptrs: []any{
   639  				new(int64),
   640  				&[]int64{},
   641  				&[1][2][3][4][5]int64{},
   642  				new(uint64),
   643  				&[]uint64{},
   644  				&[1][2][3][4][5]uint64{},
   645  			},
   646  		},
   647  		{
   648  			leaf:     newLeafF(b, "leaf", shape, unsigned, count),
   649  			dims:     shape,
   650  			hasrange: norange,
   651  			unsigned: unsigned,
   652  			lentype:  4,
   653  			offset:   0,
   654  			kind:     reflect.TypeOf(float32(0)).Kind(),
   655  			typ:      reflect.TypeOf(float32(0)),
   656  			class:    "TLeafF",
   657  			typename: "float32",
   658  			ptrs: []any{
   659  				new(float32),
   660  				&[]float32{},
   661  				&[1][2][3][4][5]float32{},
   662  			},
   663  		},
   664  		{
   665  			leaf:     newLeafD(b, "leaf", shape, unsigned, count),
   666  			dims:     shape,
   667  			hasrange: norange,
   668  			unsigned: unsigned,
   669  			lentype:  8,
   670  			offset:   0,
   671  			kind:     reflect.TypeOf(float64(0)).Kind(),
   672  			typ:      reflect.TypeOf(float64(0)),
   673  			class:    "TLeafD",
   674  			typename: "float64",
   675  			ptrs: []any{
   676  				new(float64),
   677  				&[]float64{},
   678  				&[1][2][3][4][5]float64{},
   679  			},
   680  		},
   681  		{
   682  			leaf:     newLeafF16(b, "leaf", shape, unsigned, count, nil),
   683  			dims:     shape,
   684  			hasrange: norange,
   685  			unsigned: unsigned,
   686  			lentype:  4,
   687  			offset:   0,
   688  			kind:     reflect.TypeOf(root.Float16(0)).Kind(),
   689  			typ:      reflect.TypeOf(root.Float16(0)),
   690  			class:    "TLeafF16",
   691  			typename: "root.Float16",
   692  			ptrs: []any{
   693  				new(root.Float16),
   694  				&[]root.Float16{},
   695  				&[1][2][3][4][5]root.Float16{},
   696  			},
   697  		},
   698  		{
   699  			leaf:     newLeafD32(b, "leaf", shape, unsigned, count, nil),
   700  			dims:     shape,
   701  			hasrange: norange,
   702  			unsigned: unsigned,
   703  			lentype:  8,
   704  			offset:   0,
   705  			kind:     reflect.TypeOf(root.Double32(0)).Kind(),
   706  			typ:      reflect.TypeOf(root.Double32(0)),
   707  			class:    "TLeafD32",
   708  			typename: "root.Double32",
   709  			ptrs: []any{
   710  				new(root.Double32),
   711  				&[]root.Double32{},
   712  				&[1][2][3][4][5]root.Double32{},
   713  			},
   714  		},
   715  		{
   716  			leaf:     newLeafC(b, "leaf", shape, unsigned, count),
   717  			dims:     shape,
   718  			hasrange: norange,
   719  			unsigned: unsigned,
   720  			lentype:  1,
   721  			offset:   0,
   722  			kind:     reflect.TypeOf("").Kind(),
   723  			typ:      reflect.TypeOf(""),
   724  			class:    "TLeafC",
   725  			typename: "string",
   726  			ptrs: []any{
   727  				new(string),
   728  				&[]string{},
   729  				&[1][2][3][4][5]string{},
   730  			},
   731  		},
   732  	} {
   733  		t.Run(fmt.Sprintf("%T", tc.leaf), func(t *testing.T) {
   734  			dims := tc.leaf.Shape()
   735  			if got, want := dims, tc.dims; !reflect.DeepEqual(got, want) {
   736  				t.Fatalf("invalid dims: got=%v, want=%v", got, want)
   737  			}
   738  
   739  			hasrange := tc.leaf.HasRange()
   740  			if got, want := hasrange, tc.hasrange; !reflect.DeepEqual(got, want) {
   741  				t.Fatalf("invalid hasrange: got=%v, want=%v", got, want)
   742  			}
   743  
   744  			unsigned := tc.leaf.IsUnsigned()
   745  			if got, want := unsigned, tc.unsigned; !reflect.DeepEqual(got, want) {
   746  				t.Fatalf("invalid unsigned: got=%v, want=%v", got, want)
   747  			}
   748  
   749  			lentype := tc.leaf.LenType()
   750  			if got, want := lentype, tc.lentype; !reflect.DeepEqual(got, want) {
   751  				t.Fatalf("invalid lentype: got=%v, want=%v", got, want)
   752  			}
   753  
   754  			offset := tc.leaf.Offset()
   755  			if got, want := offset, tc.offset; !reflect.DeepEqual(got, want) {
   756  				t.Fatalf("invalid offset: got=%v, want=%v", got, want)
   757  			}
   758  
   759  			kind := tc.leaf.Kind()
   760  			if got, want := kind, tc.kind; !reflect.DeepEqual(got, want) {
   761  				t.Fatalf("invalid kind: got=%v, want=%v", got, want)
   762  			}
   763  
   764  			typ := tc.leaf.Type()
   765  			if got, want := typ, tc.typ; !reflect.DeepEqual(got, want) {
   766  				t.Fatalf("invalid type: got=%v, want=%v", got, want)
   767  			}
   768  
   769  			class := tc.leaf.Class()
   770  			if got, want := class, tc.class; !reflect.DeepEqual(got, want) {
   771  				t.Fatalf("invalid class: got=%v, want=%v", got, want)
   772  			}
   773  
   774  			typename := tc.leaf.TypeName()
   775  			if got, want := typename, tc.typename; !reflect.DeepEqual(got, want) {
   776  				t.Fatalf("invalid typename: got=%v, want=%v", got, want)
   777  			}
   778  
   779  			switch leaf := tc.leaf.(type) {
   780  			case *LeafO:
   781  				min := leaf.Minimum()
   782  				max := leaf.Maximum()
   783  				if min != max || min != false {
   784  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   785  				}
   786  			case *LeafB:
   787  				min := leaf.Minimum()
   788  				max := leaf.Minimum()
   789  				if min != max || min != int8(0) {
   790  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   791  				}
   792  			case *LeafS:
   793  				min := leaf.Minimum()
   794  				max := leaf.Minimum()
   795  				if min != max || min != int16(0) {
   796  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   797  				}
   798  			case *LeafI:
   799  				min := leaf.Minimum()
   800  				max := leaf.Minimum()
   801  				if min != max || min != int32(0) {
   802  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   803  				}
   804  			case *LeafL:
   805  				min := leaf.Minimum()
   806  				max := leaf.Minimum()
   807  				if min != max || min != int64(0) {
   808  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   809  				}
   810  			case *LeafF:
   811  				min := leaf.Minimum()
   812  				max := leaf.Minimum()
   813  				if min != max || min != float32(0) {
   814  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   815  				}
   816  			case *LeafD:
   817  				min := leaf.Minimum()
   818  				max := leaf.Minimum()
   819  				if min != max || min != float64(0) {
   820  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   821  				}
   822  			case *LeafF16:
   823  				min := leaf.Minimum()
   824  				max := leaf.Minimum()
   825  				if min != max || min != root.Float16(0) {
   826  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   827  				}
   828  			case *LeafD32:
   829  				min := leaf.Minimum()
   830  				max := leaf.Minimum()
   831  				if min != max || min != root.Double32(0) {
   832  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   833  				}
   834  			case *LeafC:
   835  				min := leaf.Minimum()
   836  				max := leaf.Minimum()
   837  				if min != max || min != int32(0) {
   838  					t.Fatalf("invalid min/max: got=%v,%v", min, max)
   839  				}
   840  			}
   841  
   842  			for _, addr := range tc.ptrs {
   843  				err := tc.leaf.setAddress(addr)
   844  				if err != nil {
   845  					t.Fatalf("could not set address to %T: %+v", addr, err)
   846  				}
   847  			}
   848  		})
   849  	}
   850  }