github.com/mitranim/gg@v0.1.17/slice_test.go (about)

     1  package gg_test
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"testing"
     7  	u "unsafe"
     8  
     9  	"github.com/mitranim/gg"
    10  	"github.com/mitranim/gg/gtest"
    11  )
    12  
    13  func ExampleSlice() {
    14  	values := []string{`one`, `two`, `three`}
    15  	indexes := []int{0, 2}
    16  	result := gg.Map(indexes, gg.SliceOf(values...).Get)
    17  
    18  	fmt.Println(gg.GoString(result))
    19  
    20  	// Output:
    21  	// []string{"one", "three"}
    22  }
    23  
    24  func TestLens(t *testing.T) {
    25  	defer gtest.Catch(t)
    26  
    27  	gtest.Eq(gg.Lens[[]int](), 0)
    28  	gtest.Eq(gg.Lens([]int{}, []int{10}), 1)
    29  	gtest.Eq(gg.Lens([]int{}, []int{10}, []int{20, 30}), 3)
    30  }
    31  
    32  func BenchmarkLens(b *testing.B) {
    33  	val := [][]int{{}, {10}, {20, 30}, {40, 50, 60}}
    34  
    35  	for ind := 0; ind < b.N; ind++ {
    36  		gg.Nop1(gg.Lens(val...))
    37  	}
    38  }
    39  
    40  func TestGrowLen(t *testing.T) {
    41  	defer gtest.Catch(t)
    42  
    43  	t.Run(`from_empty`, func(t *testing.T) {
    44  		defer gtest.Catch(t)
    45  
    46  		gtest.Equal(
    47  			gg.GrowLen([]int(nil), 3),
    48  			[]int{0, 0, 0},
    49  		)
    50  	})
    51  
    52  	t.Run(`within_capacity`, func(t *testing.T) {
    53  		defer gtest.Catch(t)
    54  
    55  		src := []int{10, 20, 30, 40, 0, 0, 0, 0}
    56  		cur := src[:2]
    57  
    58  		test := func(size int, expTar, expSrc []int) {
    59  			tar := gg.GrowLen(cur, size)
    60  			gtest.Equal(src, expSrc)
    61  			gtest.Equal(tar, expTar)
    62  			gtest.Eq(cap(tar), cap(src))
    63  			gtest.Eq(u.SliceData(src), u.SliceData(tar))
    64  		}
    65  
    66  		test(0, []int{10, 20}, []int{10, 20, 30, 40, 0, 0, 0, 0})
    67  		test(1, []int{10, 20, 0}, []int{10, 20, 0, 40, 0, 0, 0, 0})
    68  		test(2, []int{10, 20, 0, 0}, []int{10, 20, 0, 0, 0, 0, 0, 0})
    69  		test(3, []int{10, 20, 0, 0, 0}, []int{10, 20, 0, 0, 0, 0, 0, 0})
    70  	})
    71  
    72  	t.Run(`exceeding_capacity`, func(t *testing.T) {
    73  		defer gtest.Catch(t)
    74  
    75  		src := []int{10, 20, 30, 40}[:2]
    76  		tar := gg.GrowLen(src, 3)
    77  
    78  		gtest.Equal(src, []int{10, 20})
    79  		gtest.Equal(tar, []int{10, 20, 0, 0, 0})
    80  		gtest.Equal(src[:4], []int{10, 20, 30, 40})
    81  		gtest.NotEq(u.SliceData(src), u.SliceData(tar))
    82  	})
    83  }
    84  
    85  func BenchmarkGrowLen(b *testing.B) {
    86  	buf := make([]byte, 0, 1024)
    87  	b.ResetTimer()
    88  
    89  	for ind := 0; ind < b.N; ind++ {
    90  		gg.Nop1(gg.GrowLen(buf, 128))
    91  	}
    92  }
    93  
    94  func TestGrowCap(t *testing.T) {
    95  	defer gtest.Catch(t)
    96  
    97  	t.Run(`from_empty`, func(t *testing.T) {
    98  		defer gtest.Catch(t)
    99  
   100  		gtest.True(gg.GrowCap([]int(nil), 0) == nil)
   101  
   102  		{
   103  			tar := gg.GrowCap([]int(nil), 8)
   104  			gtest.Eq(len(tar), 0)
   105  			gtest.Eq(cap(tar), 8)
   106  		}
   107  	})
   108  
   109  	t.Run(`within_capacity`, func(t *testing.T) {
   110  		defer gtest.Catch(t)
   111  
   112  		src := []int{10, 20, 30, 40}[:2]
   113  		tar := gg.GrowCap(src, 2)
   114  
   115  		gtest.Equal(tar, src)
   116  		gtest.Equal(tar, []int{10, 20})
   117  
   118  		gtest.Eq(u.SliceData(src), u.SliceData(tar))
   119  		gtest.Eq(len(tar), len(src))
   120  		gtest.Eq(cap(tar), cap(src))
   121  	})
   122  }
   123  
   124  func TestTruncLen(t *testing.T) {
   125  	defer gtest.Catch(t)
   126  
   127  	type Slice = []int
   128  
   129  	test := func(src Slice, size int, exp Slice) {
   130  		out := gg.TruncLen(src, size)
   131  		gtest.Equal(out, exp)
   132  
   133  		gtest.Eq(
   134  			u.SliceData(out),
   135  			u.SliceData(src),
   136  			`reslicing must preserve data pointer`,
   137  		)
   138  
   139  		gtest.Eq(
   140  			cap(out),
   141  			cap(src),
   142  			`reslicing must preserve capacity`,
   143  		)
   144  	}
   145  
   146  	test(nil, -1, nil)
   147  	test(nil, 0, nil)
   148  	test(nil, 1, nil)
   149  	test(nil, 2, nil)
   150  
   151  	test(Slice{}, -1, Slice{})
   152  	test(Slice{}, 0, Slice{})
   153  	test(Slice{}, 1, Slice{})
   154  	test(Slice{}, 2, Slice{})
   155  
   156  	src := Slice{10, 20, 30, 40}
   157  	test(src, -1, Slice{})
   158  	test(src, 0, Slice{})
   159  	test(src, 1, Slice{10})
   160  	test(src, 2, Slice{10, 20})
   161  	test(src, 3, Slice{10, 20, 30})
   162  	test(src, 4, src)
   163  	test(src, 5, src)
   164  	test(src, 6, src)
   165  }
   166  
   167  func TestTake(t *testing.T) {
   168  	defer gtest.Catch(t)
   169  
   170  	gtest.Equal(gg.Take([]int(nil), -2), []int(nil))
   171  	gtest.Equal(gg.Take([]int(nil), -1), []int(nil))
   172  	gtest.Equal(gg.Take([]int(nil), 0), []int(nil))
   173  	gtest.Equal(gg.Take([]int(nil), 1), []int(nil))
   174  	gtest.Equal(gg.Take([]int(nil), 2), []int(nil))
   175  
   176  	gtest.Equal(gg.Take([]int{}, -2), []int{})
   177  	gtest.Equal(gg.Take([]int{}, -1), []int{})
   178  	gtest.Equal(gg.Take([]int{}, 0), []int{})
   179  	gtest.Equal(gg.Take([]int{}, 1), []int{})
   180  	gtest.Equal(gg.Take([]int{}, 2), []int{})
   181  
   182  	gtest.Equal(gg.Take([]int{10}, -2), []int{})
   183  	gtest.Equal(gg.Take([]int{10}, -1), []int{})
   184  	gtest.Equal(gg.Take([]int{10}, 0), []int{})
   185  	gtest.Equal(gg.Take([]int{10}, 1), []int{10})
   186  	gtest.Equal(gg.Take([]int{10}, 2), []int{10})
   187  
   188  	gtest.Equal(gg.Take([]int{10, 20}, -2), []int{})
   189  	gtest.Equal(gg.Take([]int{10, 20}, -1), []int{})
   190  	gtest.Equal(gg.Take([]int{10, 20}, 0), []int{})
   191  	gtest.Equal(gg.Take([]int{10, 20}, 1), []int{10})
   192  	gtest.Equal(gg.Take([]int{10, 20}, 2), []int{10, 20})
   193  
   194  	gtest.Equal(gg.Take([]int{10, 20, 30}, -2), []int{})
   195  	gtest.Equal(gg.Take([]int{10, 20, 30}, -1), []int{})
   196  	gtest.Equal(gg.Take([]int{10, 20, 30}, 0), []int{})
   197  	gtest.Equal(gg.Take([]int{10, 20, 30}, 1), []int{10})
   198  	gtest.Equal(gg.Take([]int{10, 20, 30}, 2), []int{10, 20})
   199  
   200  	gtest.Equal(gg.Take([]int{10, 20, 30, 40}, -2), []int{})
   201  	gtest.Equal(gg.Take([]int{10, 20, 30, 40}, -1), []int{})
   202  	gtest.Equal(gg.Take([]int{10, 20, 30, 40}, 0), []int{})
   203  	gtest.Equal(gg.Take([]int{10, 20, 30, 40}, 1), []int{10})
   204  	gtest.Equal(gg.Take([]int{10, 20, 30, 40}, 2), []int{10, 20})
   205  }
   206  
   207  func TestDrop(t *testing.T) {
   208  	defer gtest.Catch(t)
   209  
   210  	gtest.Equal(gg.Drop([]int(nil), -2), []int(nil))
   211  	gtest.Equal(gg.Drop([]int(nil), -1), []int(nil))
   212  	gtest.Equal(gg.Drop([]int(nil), 0), []int(nil))
   213  	gtest.Equal(gg.Drop([]int(nil), 1), []int(nil))
   214  	gtest.Equal(gg.Drop([]int(nil), 2), []int(nil))
   215  
   216  	gtest.Equal(gg.Drop([]int{}, -2), []int{})
   217  	gtest.Equal(gg.Drop([]int{}, -1), []int{})
   218  	gtest.Equal(gg.Drop([]int{}, 0), []int{})
   219  	gtest.Equal(gg.Drop([]int{}, 1), []int{})
   220  	gtest.Equal(gg.Drop([]int{}, 2), []int{})
   221  
   222  	gtest.Equal(gg.Drop([]int{10}, -2), []int{10})
   223  	gtest.Equal(gg.Drop([]int{10}, -1), []int{10})
   224  	gtest.Equal(gg.Drop([]int{10}, 0), []int{10})
   225  	gtest.Equal(gg.Drop([]int{10}, 1), []int{})
   226  	gtest.Equal(gg.Drop([]int{10}, 2), []int{})
   227  
   228  	gtest.Equal(gg.Drop([]int{10, 20}, -2), []int{10, 20})
   229  	gtest.Equal(gg.Drop([]int{10, 20}, -1), []int{10, 20})
   230  	gtest.Equal(gg.Drop([]int{10, 20}, 0), []int{10, 20})
   231  	gtest.Equal(gg.Drop([]int{10, 20}, 1), []int{20})
   232  	gtest.Equal(gg.Drop([]int{10, 20}, 2), []int{})
   233  
   234  	gtest.Equal(gg.Drop([]int{10, 20, 30}, -2), []int{10, 20, 30})
   235  	gtest.Equal(gg.Drop([]int{10, 20, 30}, -1), []int{10, 20, 30})
   236  	gtest.Equal(gg.Drop([]int{10, 20, 30}, 0), []int{10, 20, 30})
   237  	gtest.Equal(gg.Drop([]int{10, 20, 30}, 1), []int{20, 30})
   238  	gtest.Equal(gg.Drop([]int{10, 20, 30}, 2), []int{30})
   239  
   240  	gtest.Equal(gg.Drop([]int{10, 20, 30, 40}, -2), []int{10, 20, 30, 40})
   241  	gtest.Equal(gg.Drop([]int{10, 20, 30, 40}, -1), []int{10, 20, 30, 40})
   242  	gtest.Equal(gg.Drop([]int{10, 20, 30, 40}, 0), []int{10, 20, 30, 40})
   243  	gtest.Equal(gg.Drop([]int{10, 20, 30, 40}, 1), []int{20, 30, 40})
   244  	gtest.Equal(gg.Drop([]int{10, 20, 30, 40}, 2), []int{30, 40})
   245  }
   246  
   247  func TestMap(t *testing.T) {
   248  	defer gtest.Catch(t)
   249  
   250  	fun := gg.Map[int, string]
   251  	elemFun := strconv.Itoa
   252  
   253  	testMapCommon(fun)
   254  
   255  	gtest.Equal(fun([]int{10, 10}, elemFun), []string{`10`, `10`})
   256  	gtest.Equal(fun([]int{10, 20, 10}, elemFun), []string{`10`, `20`, `10`})
   257  	gtest.Equal(fun([]int{10, 20, 10, 20}, elemFun), []string{`10`, `20`, `10`, `20`})
   258  	gtest.Equal(fun([]int{10, 20, 20, 10}, elemFun), []string{`10`, `20`, `20`, `10`})
   259  }
   260  
   261  func testMapCommon(mapFun func([]int, func(int) string) []string) {
   262  	elemFun := strconv.Itoa
   263  
   264  	gtest.Equal(mapFun([]int(nil), elemFun), []string(nil))
   265  	gtest.Equal(mapFun([]int{}, elemFun), []string{})
   266  	gtest.Equal(mapFun([]int{10}, elemFun), []string{`10`})
   267  	gtest.Equal(mapFun([]int{10, 20}, elemFun), []string{`10`, `20`})
   268  	gtest.Equal(mapFun([]int{10, 20, 30}, elemFun), []string{`10`, `20`, `30`})
   269  }
   270  
   271  func BenchmarkMap(b *testing.B) {
   272  	val := gg.Span(32)
   273  	b.ResetTimer()
   274  
   275  	for ind := 0; ind < b.N; ind++ {
   276  		gg.Nop1(gg.Map(val, gg.Inc[int]))
   277  	}
   278  }
   279  
   280  func TestMapMut(t *testing.T) {
   281  	defer gtest.Catch(t)
   282  
   283  	src := []int{10, 20, 30}
   284  	gtest.SliceIs(gg.MapMut(src, nil), src)
   285  	gtest.Equal(src, []int{10, 20, 30})
   286  
   287  	gtest.SliceIs(gg.MapMut(src, gg.Inc[int]), src)
   288  	gtest.Equal(src, []int{11, 21, 31})
   289  
   290  	gtest.SliceIs(gg.MapMut(src, gg.Dec[int]), src)
   291  	gtest.Equal(src, []int{10, 20, 30})
   292  
   293  	gtest.SliceIs(gg.MapMut(src, gg.Dec[int]), src)
   294  	gtest.Equal(src, []int{9, 19, 29})
   295  }
   296  
   297  func TestMapPtr(t *testing.T) {
   298  	defer gtest.Catch(t)
   299  
   300  	src := []int{10, 20, 30}
   301  	gtest.Equal(gg.MapPtr(src, DoublePtrStr), []string{`20`, `40`, `60`})
   302  	gtest.Equal(src, []int{20, 40, 60})
   303  }
   304  
   305  func DoublePtrStr(ptr *int) string {
   306  	*ptr *= 2
   307  	return gg.String(*ptr)
   308  }
   309  
   310  func TestMap2(t *testing.T) {
   311  	defer gtest.Catch(t)
   312  
   313  	gtest.Equal(
   314  		gg.Map2([]int(nil), []int(nil), gg.Plus2[int]),
   315  		[]int(nil),
   316  	)
   317  
   318  	gtest.Equal(
   319  		gg.Map2([]int{}, []int(nil), gg.Plus2[int]),
   320  		[]int(nil),
   321  	)
   322  
   323  	gtest.Equal(
   324  		gg.Map2([]int(nil), []int{}, gg.Plus2[int]),
   325  		[]int(nil),
   326  	)
   327  
   328  	gtest.Equal(
   329  		gg.Map2([]int{}, []int{}, gg.Plus2[int]),
   330  		[]int{},
   331  	)
   332  
   333  	gtest.PanicStr(`length mismatch`, func() {
   334  		gg.Map2([]int{}, []int{10}, gg.Plus2[int])
   335  	})
   336  
   337  	gtest.PanicStr(`length mismatch`, func() {
   338  		gg.Map2([]int{10}, []int{}, gg.Plus2[int])
   339  	})
   340  
   341  	gtest.Equal(
   342  		gg.Map2([]int{10, 20, 30}, []int{40, 50, 60}, gg.Plus2[int]),
   343  		[]int{50, 70, 90},
   344  	)
   345  }
   346  
   347  func TestMapFlat(t *testing.T) {
   348  	defer gtest.Catch(t)
   349  
   350  	fun := gg.MapFlat[[]string, int, string]
   351  	elemFun := itoaPair
   352  
   353  	testMapFlatCommon(fun)
   354  
   355  	gtest.Equal(fun([]int{10}, elemFun), []string{`10`, `10`})
   356  	gtest.Equal(fun([]int{10, 10}, elemFun), []string{`10`, `10`, `10`, `10`})
   357  	gtest.Equal(fun([]int{10, 20}, elemFun), []string{`10`, `10`, `20`, `20`})
   358  }
   359  
   360  func itoaPair(src int) []string {
   361  	return []string{strconv.Itoa(src), strconv.Itoa(src)}
   362  }
   363  
   364  func testMapFlatCommon(fun func([]int, func(int) []string) []string) {
   365  	gtest.Equal(
   366  		fun([]int(nil), intStrPair),
   367  		[]string(nil),
   368  	)
   369  
   370  	gtest.Equal(
   371  		fun([]int{}, intStrPair),
   372  		[]string(nil),
   373  	)
   374  
   375  	gtest.Equal(
   376  		fun([]int{10}, intStrPair),
   377  		[]string{`9`, `11`},
   378  	)
   379  
   380  	gtest.Equal(
   381  		fun([]int{10, 20}, intStrPair),
   382  		[]string{`9`, `11`, `19`, `21`},
   383  	)
   384  
   385  	gtest.Equal(
   386  		fun([]int{10, 20, 30}, intStrPair),
   387  		[]string{`9`, `11`, `19`, `21`, `29`, `31`},
   388  	)
   389  }
   390  
   391  func BenchmarkMapFlat(b *testing.B) {
   392  	val := gg.Span(32)
   393  	b.ResetTimer()
   394  
   395  	for ind := 0; ind < b.N; ind++ {
   396  		gg.Nop1(gg.MapFlat(val, intPair))
   397  	}
   398  }
   399  
   400  func TestMapUniq(t *testing.T) {
   401  	defer gtest.Catch(t)
   402  
   403  	fun := gg.MapUniq[int, string]
   404  	elemFun := strconv.Itoa
   405  
   406  	testMapCommon(fun)
   407  
   408  	gtest.Equal(fun([]int{10, 10}, elemFun), []string{`10`})
   409  	gtest.Equal(fun([]int{10, 20, 10}, elemFun), []string{`10`, `20`})
   410  	gtest.Equal(fun([]int{10, 20, 10, 20}, elemFun), []string{`10`, `20`})
   411  	gtest.Equal(fun([]int{10, 20, 20, 10}, elemFun), []string{`10`, `20`})
   412  }
   413  
   414  func TestMapFlatUniq(t *testing.T) {
   415  	defer gtest.Catch(t)
   416  
   417  	fun := gg.MapFlatUniq[[]string, int, string]
   418  	elemFun := itoaPair
   419  
   420  	testMapFlatCommon(fun)
   421  
   422  	gtest.Equal(fun([]int{10}, elemFun), []string{`10`})
   423  	gtest.Equal(fun([]int{10, 10}, elemFun), []string{`10`})
   424  	gtest.Equal(fun([]int{10, 20}, elemFun), []string{`10`, `20`})
   425  	gtest.Equal(fun([]int{10, 20, 20, 10}, elemFun), []string{`10`, `20`})
   426  }
   427  
   428  func TestIndex(t *testing.T) {
   429  	defer gtest.Catch(t)
   430  
   431  	type Slice = []int
   432  	type Map = map[int]int
   433  
   434  	gtest.Zero(gg.Index[Slice, int, int](Slice(nil), nil))
   435  	gtest.Zero(gg.Index[Slice, int, int](Slice{10, 20}, nil))
   436  	gtest.Equal(gg.Index(Slice(nil), gg.Inc[int]), Map{})
   437  
   438  	gtest.Equal(
   439  		gg.Index(Slice{10, 20}, gg.Inc[int]),
   440  		Map{11: 10, 21: 20},
   441  	)
   442  }
   443  
   444  func TestIndexInto(t *testing.T) {
   445  	defer gtest.Catch(t)
   446  
   447  	type Map = map[int]int
   448  	tar := Map{}
   449  
   450  	gg.IndexInto(tar, nil, nil)
   451  	gtest.Equal(tar, Map{})
   452  
   453  	gg.IndexInto(tar, []int{10, 20}, nil)
   454  	gtest.Equal(tar, Map{})
   455  
   456  	gg.IndexInto(tar, []int{10, 20}, gg.Inc[int])
   457  	gtest.Equal(tar, Map{11: 10, 21: 20})
   458  }
   459  
   460  func TestIndexPair(t *testing.T) {
   461  	defer gtest.Catch(t)
   462  
   463  	type Slice = []int
   464  	type Map = map[int]int
   465  
   466  	gtest.Zero(gg.IndexPair[Slice, int, int, int](Slice(nil), nil))
   467  	gtest.Zero(gg.IndexPair[Slice, int, int, int](Slice{10, 20}, nil))
   468  	gtest.Zero(gg.IndexPair(Slice(nil), ToPair[int]))
   469  
   470  	gtest.Equal(
   471  		gg.IndexPair(Slice{10, 20}, ToPair[int]),
   472  		Map{9: 11, 19: 21},
   473  	)
   474  }
   475  
   476  func TestIndexPairInto(t *testing.T) {
   477  	defer gtest.Catch(t)
   478  
   479  	type Map = map[int]int
   480  	tar := Map{}
   481  
   482  	gg.IndexPairInto[int](tar, nil, nil)
   483  	gtest.Equal(tar, Map{})
   484  
   485  	gg.IndexPairInto(tar, []int{10, 20}, nil)
   486  	gtest.Equal(tar, Map{})
   487  
   488  	gg.IndexPairInto(tar, []int{10, 20}, ToPair[int])
   489  	gtest.Equal(tar, Map{9: 11, 19: 21})
   490  }
   491  
   492  func TestTimes(t *testing.T) {
   493  	defer gtest.Catch(t)
   494  
   495  	gtest.Zero(gg.Times[string](-1, nil))
   496  	gtest.Zero(gg.Times[string](0, nil))
   497  	gtest.Zero(gg.Times[string](1, nil))
   498  	gtest.Zero(gg.Times(-1, gg.String[int]))
   499  	gtest.Zero(gg.Times(0, gg.String[int]))
   500  
   501  	gtest.Equal(gg.Times(1, gg.String[int]), []string{`0`})
   502  	gtest.Equal(gg.Times(2, gg.String[int]), []string{`0`, `1`})
   503  	gtest.Equal(gg.Times(3, gg.String[int]), []string{`0`, `1`, `2`})
   504  }
   505  
   506  func TestTimesAppend(t *testing.T) {
   507  	defer gtest.Catch(t)
   508  
   509  	gtest.NotPanic(func() {
   510  		gg.TimesAppend((*[]string)(nil), -1, nil)
   511  		gg.TimesAppend((*[]string)(nil), 0, nil)
   512  		gg.TimesAppend((*[]string)(nil), 1, nil)
   513  
   514  		gg.TimesAppend((*[]string)(nil), -1, gg.String[int])
   515  		gg.TimesAppend((*[]string)(nil), 0, gg.String[int])
   516  		gg.TimesAppend((*[]string)(nil), 1, gg.String[int])
   517  	})
   518  
   519  	var tar []string
   520  
   521  	gg.TimesAppend(&tar, -1, gg.String[int])
   522  	gtest.Zero(tar)
   523  
   524  	gg.TimesAppend(&tar, 0, gg.String[int])
   525  	gtest.Zero(tar)
   526  
   527  	gg.TimesAppend(&tar, 1, gg.String[int])
   528  	gtest.Equal(tar, []string{`0`})
   529  
   530  	gg.TimesAppend(&tar, 2, gg.String[int])
   531  	gtest.Equal(tar, []string{`0`, `0`, `1`})
   532  
   533  	gg.TimesAppend(&tar, 3, gg.String[int])
   534  	gtest.Equal(tar, []string{`0`, `0`, `1`, `0`, `1`, `2`})
   535  }
   536  
   537  func TestCount(t *testing.T) {
   538  	defer gtest.Catch(t)
   539  
   540  	gtest.Zero(gg.Count([]int(nil), nil))
   541  	gtest.Zero(gg.Count([]int{}, nil))
   542  	gtest.Zero(gg.Count([]int{10}, nil))
   543  	gtest.Zero(gg.Count([]int{10, 20}, nil))
   544  
   545  	gtest.Zero(gg.Count([]int(nil), False1[int]))
   546  	gtest.Zero(gg.Count([]int{}, False1[int]))
   547  	gtest.Zero(gg.Count([]int{10}, False1[int]))
   548  	gtest.Zero(gg.Count([]int{10, 20}, False1[int]))
   549  
   550  	gtest.Zero(gg.Count([]int(nil), True1[int]))
   551  	gtest.Zero(gg.Count([]int{}, True1[int]))
   552  
   553  	gtest.Eq(gg.Count([]int{10}, True1[int]), 1)
   554  	gtest.Eq(gg.Count([]int{10, 20}, True1[int]), 2)
   555  	gtest.Eq(gg.Count([]int{10, 20, 30}, True1[int]), 3)
   556  
   557  	gtest.Eq(gg.Count([]int{-10, 10, -20, 20, -30}, gg.IsNeg[int]), 3)
   558  	gtest.Eq(gg.Count([]int{-10, 10, -20, 20, -30}, gg.IsPos[int]), 2)
   559  }
   560  
   561  func TestFold(t *testing.T) {
   562  	defer gtest.Catch(t)
   563  
   564  	const acc = 10
   565  	gtest.Eq(gg.Fold([]int(nil), acc, nil), acc)
   566  	gtest.Eq(gg.Fold([]int{}, acc, nil), acc)
   567  	gtest.Eq(gg.Fold([]int{20}, acc, nil), acc)
   568  	gtest.Eq(gg.Fold([]int{20, 30}, acc, nil), acc)
   569  
   570  	gtest.Eq(gg.Fold([]int{20}, 10, gg.SubUncheck[int]), 10-20)
   571  	gtest.Eq(gg.Fold([]int{20}, 10, gg.Plus2[int]), 10+20)
   572  
   573  	gtest.Eq(gg.Fold([]int{20, 30}, 10, gg.SubUncheck[int]), 10-20-30)
   574  	gtest.Eq(gg.Fold([]int{20, 30}, 10, gg.Plus2[int]), 10+20+30)
   575  
   576  	gtest.Eq(gg.Fold([]int{20, 30, 40}, 10, gg.SubUncheck[int]), 10-20-30-40)
   577  	gtest.Eq(gg.Fold([]int{20, 30, 40}, 10, gg.Plus2[int]), 10+20+30+40)
   578  }
   579  
   580  func TestFoldz(t *testing.T) {
   581  	defer gtest.Catch(t)
   582  
   583  	gtest.Zero(gg.Foldz[int]([]int(nil), nil))
   584  	gtest.Zero(gg.Foldz[int]([]int{}, nil))
   585  	gtest.Zero(gg.Foldz[int]([]int{10}, nil))
   586  	gtest.Zero(gg.Foldz[int]([]int{10, 20}, nil))
   587  
   588  	gtest.Eq(gg.Foldz([]int{10}, gg.SubUncheck[int]), 0-10)
   589  	gtest.Eq(gg.Foldz([]int{10}, gg.Plus2[int]), 0+10)
   590  
   591  	gtest.Eq(gg.Foldz([]int{10, 20}, gg.SubUncheck[int]), 0-10-20)
   592  	gtest.Eq(gg.Foldz([]int{10, 20}, gg.Plus2[int]), 0+10+20)
   593  
   594  	gtest.Eq(gg.Foldz([]int{10, 20, 30}, gg.SubUncheck[int]), 0-10-20-30)
   595  	gtest.Eq(gg.Foldz([]int{10, 20, 30}, gg.Plus2[int]), 0+10+20+30)
   596  }
   597  
   598  func TestFold1(t *testing.T) {
   599  	defer gtest.Catch(t)
   600  
   601  	gtest.Zero(gg.Fold1[int]([]int(nil), nil))
   602  	gtest.Zero(gg.Fold1[int]([]int{}, nil))
   603  
   604  	gtest.Eq(gg.Fold1([]int{10}, nil), 10)
   605  	gtest.Eq(gg.Fold1([]int{10}, gg.SubUncheck[int]), 10)
   606  	gtest.Eq(gg.Fold1([]int{10}, gg.Plus2[int]), 10)
   607  
   608  	gtest.Eq(gg.Fold1([]int{10, 20}, nil), 10)
   609  	gtest.Eq(gg.Fold1([]int{10, 20}, gg.SubUncheck[int]), 10-20)
   610  	gtest.Eq(gg.Fold1([]int{10, 20}, gg.Plus2[int]), 10+20)
   611  
   612  	gtest.Eq(gg.Fold1([]int{10, 20, 30}, nil), 10)
   613  	gtest.Eq(gg.Fold1([]int{10, 20, 30}, gg.SubUncheck[int]), 10-20-30)
   614  	gtest.Eq(gg.Fold1([]int{10, 20, 30}, gg.Plus2[int]), 10+20+30)
   615  }
   616  
   617  func TestFilter(t *testing.T) {
   618  	defer gtest.Catch(t)
   619  
   620  	type Src = []int
   621  
   622  	gtest.Zero(gg.Filter(Src(nil), nil))
   623  	gtest.Zero(gg.Filter(Src{}, nil))
   624  	gtest.Zero(gg.Filter(Src{10}, nil))
   625  	gtest.Zero(gg.Filter(Src{10, 20}, nil))
   626  	gtest.Zero(gg.Filter(Src{10, 20, 30}, nil))
   627  	gtest.Zero(gg.Filter(Src{10, 20, 30}, False1[int]))
   628  
   629  	gtest.Equal(gg.Filter(Src{10}, True1[int]), Src{10})
   630  	gtest.Equal(gg.Filter(Src{10, 20}, True1[int]), Src{10, 20})
   631  	gtest.Equal(gg.Filter(Src{10, 20, 30}, True1[int]), Src{10, 20, 30})
   632  
   633  	gtest.Equal(
   634  		gg.Filter(Src{-10, 10, -20, 20, -30}, gg.IsNeg[int]),
   635  		Src{-10, -20, -30},
   636  	)
   637  
   638  	gtest.Equal(
   639  		gg.Filter(Src{-10, 10, -20, 20, -30}, gg.IsPos[int]),
   640  		Src{10, 20},
   641  	)
   642  }
   643  
   644  func TestFilterAppend(t *testing.T) {
   645  	defer gtest.Catch(t)
   646  
   647  	type Type = []int
   648  
   649  	gtest.NotPanic(func() {
   650  		gg.FilterAppend((*Type)(nil), nil, nil)
   651  		gg.FilterAppend((*Type)(nil), nil, True1[int])
   652  		gg.FilterAppend((*Type)(nil), Type{}, True1[int])
   653  		gg.FilterAppend((*Type)(nil), Type{10}, True1[int])
   654  		gg.FilterAppend((*Type)(nil), Type{10, 20}, True1[int])
   655  	})
   656  
   657  	var tar Type
   658  
   659  	gg.FilterAppend(&tar, nil, True1[int])
   660  	gtest.Zero(tar)
   661  
   662  	gg.FilterAppend(&tar, Type{}, True1[int])
   663  	gtest.Zero(tar)
   664  
   665  	gg.FilterAppend(&tar, Type{10}, True1[int])
   666  	gtest.Equal(tar, Type{10})
   667  
   668  	gg.FilterAppend(&tar, Type{20, 30}, True1[int])
   669  	gtest.Equal(tar, Type{10, 20, 30})
   670  
   671  	gg.FilterAppend(&tar, Type{40, 50}, False1[int])
   672  	gtest.Equal(tar, Type{10, 20, 30})
   673  
   674  	gg.FilterAppend(&tar, Type{-10, 10, -20, 20, -30}, gg.IsNeg[int])
   675  	gtest.Equal(tar, Type{10, 20, 30, -10, -20, -30})
   676  }
   677  
   678  func TestReject(t *testing.T) {
   679  	defer gtest.Catch(t)
   680  
   681  	type Src = []int
   682  
   683  	gtest.Zero(gg.Reject(Src(nil), nil))
   684  	gtest.Zero(gg.Reject(Src{}, nil))
   685  	gtest.Zero(gg.Reject(Src{10}, nil))
   686  	gtest.Zero(gg.Reject(Src{10, 20}, nil))
   687  	gtest.Zero(gg.Reject(Src{10, 20, 30}, nil))
   688  	gtest.Zero(gg.Reject(Src{10, 20, 30}, True1[int]))
   689  
   690  	gtest.Equal(gg.Reject(Src{10}, False1[int]), Src{10})
   691  	gtest.Equal(gg.Reject(Src{10, 20}, False1[int]), Src{10, 20})
   692  	gtest.Equal(gg.Reject(Src{10, 20, 30}, False1[int]), Src{10, 20, 30})
   693  
   694  	gtest.Equal(
   695  		gg.Reject(Src{-10, 10, -20, 20, -30}, gg.IsNeg[int]),
   696  		Src{10, 20},
   697  	)
   698  
   699  	gtest.Equal(
   700  		gg.Reject(Src{-10, 10, -20, 20, -30}, gg.IsPos[int]),
   701  		Src{-10, -20, -30},
   702  	)
   703  }
   704  
   705  func TestRejectAppend(t *testing.T) {
   706  	defer gtest.Catch(t)
   707  
   708  	type Type = []int
   709  
   710  	gtest.NotPanic(func() {
   711  		gg.RejectAppend((*Type)(nil), nil, nil)
   712  		gg.RejectAppend((*Type)(nil), nil, False1[int])
   713  		gg.RejectAppend((*Type)(nil), Type{}, False1[int])
   714  		gg.RejectAppend((*Type)(nil), Type{10}, False1[int])
   715  		gg.RejectAppend((*Type)(nil), Type{10, 20}, False1[int])
   716  	})
   717  
   718  	var tar Type
   719  
   720  	gg.RejectAppend(&tar, nil, False1[int])
   721  	gtest.Zero(tar)
   722  
   723  	gg.RejectAppend(&tar, Type{}, False1[int])
   724  	gtest.Zero(tar)
   725  
   726  	gg.RejectAppend(&tar, Type{10}, False1[int])
   727  	gtest.Equal(tar, Type{10})
   728  
   729  	gg.RejectAppend(&tar, Type{20, 30}, False1[int])
   730  	gtest.Equal(tar, Type{10, 20, 30})
   731  
   732  	gg.RejectAppend(&tar, Type{40, 50}, True1[int])
   733  	gtest.Equal(tar, Type{10, 20, 30})
   734  
   735  	gg.RejectAppend(&tar, Type{-10, 10, -20, 20, -30}, gg.IsPos[int])
   736  	gtest.Equal(tar, Type{10, 20, 30, -10, -20, -30})
   737  }
   738  
   739  func TestFilterIndex(t *testing.T) {
   740  	defer gtest.Catch(t)
   741  
   742  	type Type = []int
   743  
   744  	gtest.Zero(gg.FilterIndex(Type(nil), nil))
   745  	gtest.Zero(gg.FilterIndex(Type{}, nil))
   746  	gtest.Zero(gg.FilterIndex(Type{10, 20, 30}, nil))
   747  	gtest.Zero(gg.FilterIndex(Type{10, 20, 30}, False1[int]))
   748  
   749  	gtest.Equal(gg.FilterIndex(Type{10}, True1[int]), []int{0})
   750  	gtest.Equal(gg.FilterIndex(Type{10, 20}, True1[int]), []int{0, 1})
   751  	gtest.Equal(gg.FilterIndex(Type{10, 20, 30}, True1[int]), []int{0, 1, 2})
   752  
   753  	gtest.Equal(gg.FilterIndex(Type{-10, 10, -20, 20, -30}, gg.IsNeg[int]), []int{0, 2, 4})
   754  	gtest.Equal(gg.FilterIndex(Type{-10, 10, -20, 20, -30}, gg.IsPos[int]), []int{1, 3})
   755  }
   756  
   757  func TestZeroIndex(t *testing.T) {
   758  	defer gtest.Catch(t)
   759  
   760  	type Type = []int
   761  
   762  	gtest.Zero(gg.ZeroIndex(Type(nil)))
   763  	gtest.Zero(gg.ZeroIndex(Type{}))
   764  	gtest.Zero(gg.ZeroIndex(Type{10}))
   765  	gtest.Zero(gg.ZeroIndex(Type{10, 20}))
   766  	gtest.Zero(gg.ZeroIndex(Type{10, 20, 30}))
   767  
   768  	gtest.Equal(gg.ZeroIndex(Type{0}), []int{0})
   769  	gtest.Equal(gg.ZeroIndex(Type{0, 0}), []int{0, 1})
   770  	gtest.Equal(gg.ZeroIndex(Type{0, 0, 0}), []int{0, 1, 2})
   771  
   772  	gtest.Equal(gg.ZeroIndex(Type{0, 10}), []int{0})
   773  	gtest.Equal(gg.ZeroIndex(Type{0, 10, 0}), []int{0, 2})
   774  	gtest.Equal(gg.ZeroIndex(Type{0, 10, 0, 20}), []int{0, 2})
   775  	gtest.Equal(gg.ZeroIndex(Type{0, 10, 0, 20, 0}), []int{0, 2, 4})
   776  
   777  	gtest.Equal(gg.ZeroIndex(Type{10, 0, 20, 0, 30}), []int{1, 3})
   778  }
   779  
   780  func TestNotZeroIndex(t *testing.T) {
   781  	defer gtest.Catch(t)
   782  
   783  	type Type = []int
   784  
   785  	gtest.Zero(gg.NotZeroIndex(Type(nil)))
   786  	gtest.Zero(gg.NotZeroIndex(Type{}))
   787  	gtest.Zero(gg.NotZeroIndex(Type{0}))
   788  	gtest.Zero(gg.NotZeroIndex(Type{0, 0}))
   789  	gtest.Zero(gg.NotZeroIndex(Type{0, 0, 0}))
   790  
   791  	gtest.Equal(gg.NotZeroIndex(Type{10}), []int{0})
   792  	gtest.Equal(gg.NotZeroIndex(Type{10, 20}), []int{0, 1})
   793  	gtest.Equal(gg.NotZeroIndex(Type{10, 20, 30}), []int{0, 1, 2})
   794  
   795  	gtest.Equal(gg.NotZeroIndex(Type{10, 0}), []int{0})
   796  	gtest.Equal(gg.NotZeroIndex(Type{10, 0, 20}), []int{0, 2})
   797  	gtest.Equal(gg.NotZeroIndex(Type{10, 0, 20, 0}), []int{0, 2})
   798  	gtest.Equal(gg.NotZeroIndex(Type{10, 0, 20, 0, 30}), []int{0, 2, 4})
   799  
   800  	gtest.Equal(gg.NotZeroIndex(Type{0, 10, 0, 20, 0}), []int{1, 3})
   801  }
   802  
   803  func TestCompact(t *testing.T) {
   804  	defer gtest.Catch(t)
   805  
   806  	type Type = []int
   807  
   808  	gtest.Zero(gg.Compact(Type(nil)))
   809  	gtest.Zero(gg.Compact(Type{}))
   810  	gtest.Zero(gg.Compact(Type{0}))
   811  	gtest.Zero(gg.Compact(Type{0, 0}))
   812  	gtest.Zero(gg.Compact(Type{0, 0, 0}))
   813  
   814  	gtest.Equal(gg.Compact(Type{10}), Type{10})
   815  	gtest.Equal(gg.Compact(Type{10, 20}), Type{10, 20})
   816  	gtest.Equal(gg.Compact(Type{10, 20, 30}), Type{10, 20, 30})
   817  
   818  	gtest.Equal(gg.Compact(Type{10, 0, 20, 0, 30}), Type{10, 20, 30})
   819  	gtest.Equal(gg.Compact(Type{0, 10, 0, 20, 0}), Type{10, 20})
   820  }
   821  
   822  func TestFindIndex(t *testing.T) {
   823  	defer gtest.Catch(t)
   824  
   825  	type Type = []int
   826  
   827  	gtest.Eq(gg.FindIndex(Type(nil), nil), -1)
   828  	gtest.Eq(gg.FindIndex(Type{}, nil), -1)
   829  	gtest.Eq(gg.FindIndex(Type{0}, nil), -1)
   830  	gtest.Eq(gg.FindIndex(Type{10}, nil), -1)
   831  	gtest.Eq(gg.FindIndex(Type{10, 20}, nil), -1)
   832  	gtest.Eq(gg.FindIndex(Type{10, 20, 30}, nil), -1)
   833  
   834  	gtest.Eq(gg.FindIndex(Type{10}, False1[int]), -1)
   835  	gtest.Eq(gg.FindIndex(Type{10, 20}, False1[int]), -1)
   836  	gtest.Eq(gg.FindIndex(Type{10, 20, 30}, False1[int]), -1)
   837  
   838  	gtest.Eq(gg.FindIndex(Type{10}, True1[int]), 0)
   839  	gtest.Eq(gg.FindIndex(Type{10, 20}, True1[int]), 0)
   840  	gtest.Eq(gg.FindIndex(Type{10, 20, 30}, True1[int]), 0)
   841  
   842  	gtest.Eq(gg.FindIndex(Type{10}, gg.IsNeg[int]), -1)
   843  	gtest.Eq(gg.FindIndex(Type{-10}, gg.IsNeg[int]), 0)
   844  	gtest.Eq(gg.FindIndex(Type{-10, 10}, gg.IsNeg[int]), 0)
   845  	gtest.Eq(gg.FindIndex(Type{10, -10}, gg.IsNeg[int]), 1)
   846  	gtest.Eq(gg.FindIndex(Type{10, -10, 20}, gg.IsNeg[int]), 1)
   847  	gtest.Eq(gg.FindIndex(Type{10, -10, 20, -20}, gg.IsNeg[int]), 1)
   848  }
   849  
   850  func TestFound(t *testing.T) {
   851  	defer gtest.Catch(t)
   852  
   853  	type Type = []int
   854  
   855  	gtest.Zero(gg.Tuple2(gg.Found(Type(nil), nil)))
   856  	gtest.Zero(gg.Tuple2(gg.Found(Type{}, nil)))
   857  	gtest.Zero(gg.Tuple2(gg.Found(Type{10}, nil)))
   858  	gtest.Zero(gg.Tuple2(gg.Found(Type{10, 20}, nil)))
   859  	gtest.Zero(gg.Tuple2(gg.Found(Type{10, 20, 30}, nil)))
   860  
   861  	gtest.Zero(gg.Tuple2(gg.Found(Type(nil), False1[int])))
   862  	gtest.Zero(gg.Tuple2(gg.Found(Type{}, False1[int])))
   863  	gtest.Zero(gg.Tuple2(gg.Found(Type{10}, False1[int])))
   864  	gtest.Zero(gg.Tuple2(gg.Found(Type{10, 20}, False1[int])))
   865  	gtest.Zero(gg.Tuple2(gg.Found(Type{10, 20, 30}, False1[int])))
   866  
   867  	gtest.Eq(
   868  		gg.Tuple2(gg.Found(Type{10}, True1[int])),
   869  		gg.Tuple2(10, true),
   870  	)
   871  
   872  	gtest.Eq(
   873  		gg.Tuple2(gg.Found(Type{10, 20}, True1[int])),
   874  		gg.Tuple2(10, true),
   875  	)
   876  
   877  	gtest.Eq(
   878  		gg.Tuple2(gg.Found(Type{-10, 10, -20, 20}, gg.IsNeg[int])),
   879  		gg.Tuple2(-10, true),
   880  	)
   881  
   882  	gtest.Eq(
   883  		gg.Tuple2(gg.Found(Type{-10, 10, -20, 20}, gg.IsPos[int])),
   884  		gg.Tuple2(10, true),
   885  	)
   886  }
   887  
   888  func TestFind(t *testing.T) {
   889  	defer gtest.Catch(t)
   890  
   891  	type Type = []int
   892  
   893  	gtest.Zero(gg.Find(Type(nil), nil))
   894  	gtest.Zero(gg.Find(Type{}, nil))
   895  	gtest.Zero(gg.Find(Type{10}, nil))
   896  	gtest.Zero(gg.Find(Type{10, 20}, nil))
   897  	gtest.Zero(gg.Find(Type{10, 20, 30}, nil))
   898  
   899  	gtest.Zero(gg.Find(Type(nil), False1[int]))
   900  	gtest.Zero(gg.Find(Type{}, False1[int]))
   901  	gtest.Zero(gg.Find(Type{10}, False1[int]))
   902  	gtest.Zero(gg.Find(Type{10, 20}, False1[int]))
   903  	gtest.Zero(gg.Find(Type{10, 20, 30}, False1[int]))
   904  
   905  	gtest.Eq(gg.Find(Type{10}, True1[int]), 10)
   906  	gtest.Eq(gg.Find(Type{10, 20}, True1[int]), 10)
   907  	gtest.Eq(gg.Find(Type{-10, 10, -20, 20}, gg.IsNeg[int]), -10)
   908  	gtest.Eq(gg.Find(Type{-10, 10, -20, 20}, gg.IsPos[int]), 10)
   909  }
   910  
   911  func TestProcured(t *testing.T) {
   912  	defer gtest.Catch(t)
   913  
   914  	type Type = []int
   915  
   916  	gtest.Zero(gg.Tuple2(gg.Procured[int](Type(nil), nil)))
   917  
   918  	gtest.Zero(gg.Tuple2(gg.Procured(Type{10, 20, 30}, Id1False[int])))
   919  
   920  	gtest.Eq(
   921  		gg.Tuple2(gg.Procured(Type{0, 10}, Id1True[int])),
   922  		gg.Tuple2(0, true),
   923  	)
   924  
   925  	gtest.Eq(
   926  		gg.Tuple2(gg.Procured(Type{10, 20, 30}, Id1True[int])),
   927  		gg.Tuple2(10, true),
   928  	)
   929  }
   930  
   931  func TestProcure(t *testing.T) {
   932  	defer gtest.Catch(t)
   933  
   934  	type Type = []int
   935  
   936  	gtest.Zero(gg.Procure[int](Type(nil), nil))
   937  	gtest.Zero(gg.Procure(Type{-1}, gg.Inc[int]))
   938  	gtest.Zero(gg.Procure(Type{1}, gg.Dec[int]))
   939  
   940  	gtest.Eq(gg.Procure(Type{10}, gg.Inc[int]), 11)
   941  	gtest.Eq(gg.Procure(Type{-1, 10}, gg.Inc[int]), 11)
   942  	gtest.Eq(gg.Procure(Type{-1, -1, 10}, gg.Inc[int]), 11)
   943  	gtest.Eq(gg.Procure(Type{-1, -1, 10, 20}, gg.Inc[int]), 11)
   944  
   945  	gtest.Eq(gg.Procure(Type{10}, gg.Dec[int]), 9)
   946  	gtest.Eq(gg.Procure(Type{1, 10}, gg.Dec[int]), 9)
   947  	gtest.Eq(gg.Procure(Type{1, 1, 10}, gg.Dec[int]), 9)
   948  	gtest.Eq(gg.Procure(Type{1, 1, 10, 20}, gg.Dec[int]), 9)
   949  }
   950  
   951  func TestAdjoin(t *testing.T) {
   952  	defer gtest.Catch(t)
   953  
   954  	type Type = []int
   955  
   956  	gtest.Equal(gg.Adjoin(Type(nil), 0), Type{0})
   957  	gtest.Equal(gg.Adjoin(Type(nil), 10), Type{10})
   958  
   959  	gtest.Equal(gg.Adjoin(Type{10, 20, 30}, 10), Type{10, 20, 30})
   960  	gtest.Equal(gg.Adjoin(Type{10, 20, 30}, 20), Type{10, 20, 30})
   961  	gtest.Equal(gg.Adjoin(Type{10, 20, 30}, 30), Type{10, 20, 30})
   962  	gtest.Equal(gg.Adjoin(Type{10, 20, 30}, 0), Type{10, 20, 30, 0})
   963  	gtest.Equal(gg.Adjoin(Type{10, 20, 30}, 40), Type{10, 20, 30, 40})
   964  }
   965  
   966  func TestExclude(t *testing.T) {
   967  	defer gtest.Catch(t)
   968  
   969  	type Type = []int
   970  
   971  	gtest.Zero(gg.Exclude(Type(nil), 0))
   972  	gtest.Zero(gg.Exclude(Type(nil), 10))
   973  	gtest.Zero(gg.Exclude(Type{}, 0))
   974  	gtest.Zero(gg.Exclude(Type{}, 10))
   975  	gtest.Zero(gg.Exclude(Type{0}, 0))
   976  	gtest.Zero(gg.Exclude(Type{0, 0}, 0))
   977  	gtest.Zero(gg.Exclude(Type{10}, 10))
   978  	gtest.Zero(gg.Exclude(Type{10, 10}, 10))
   979  
   980  	gtest.Equal(gg.Exclude(Type{10, 20, 30}, 40), Type{10, 20, 30})
   981  	gtest.Equal(gg.Exclude(Type{10, 20, 30}, 10), Type{20, 30})
   982  	gtest.Equal(gg.Exclude(Type{10, 20, 30}, 20), Type{10, 30})
   983  	gtest.Equal(gg.Exclude(Type{10, 20, 30}, 30), Type{10, 20})
   984  }
   985  
   986  func TestExcludeFrom(t *testing.T) {
   987  	defer gtest.Catch(t)
   988  
   989  	type Type = []int
   990  
   991  	gtest.Zero(gg.ExcludeFrom(Type(nil)))
   992  	gtest.Zero(gg.ExcludeFrom(Type{}))
   993  
   994  	gtest.Zero(gg.ExcludeFrom(Type{10}, Type{10}))
   995  
   996  	gtest.Zero(gg.ExcludeFrom(Type{10, 20}, Type{10, 20}))
   997  	gtest.Zero(gg.ExcludeFrom(Type{10, 20}, Type{10, 20, 30}))
   998  	gtest.Zero(gg.ExcludeFrom(Type{10, 20}, Type{10, 20}, Type{30}))
   999  	gtest.Zero(gg.ExcludeFrom(Type{10, 20}, Type{10}, Type{20, 30}))
  1000  	gtest.Zero(gg.ExcludeFrom(Type{10, 20}, Type{10}, Type{20}))
  1001  	gtest.Zero(gg.ExcludeFrom(Type{10, 20}, Type{10}, Type{20}, Type{30}))
  1002  
  1003  	gtest.Equal(
  1004  		gg.ExcludeFrom(Type{10, 20, 30}, Type{10}),
  1005  		Type{20, 30},
  1006  	)
  1007  
  1008  	gtest.Equal(
  1009  		gg.ExcludeFrom(Type{10, 20, 30}, Type{20}),
  1010  		Type{10, 30},
  1011  	)
  1012  
  1013  	gtest.Equal(
  1014  		gg.ExcludeFrom(Type{10, 20, 30}, Type{20}, Type{10}),
  1015  		Type{30},
  1016  	)
  1017  }
  1018  
  1019  func BenchmarkSubtract(b *testing.B) {
  1020  	base := []int{10, 20, 30, 40, 50, 60}
  1021  	sub := [][]int{{10, 20}, {50}}
  1022  
  1023  	for ind := 0; ind < b.N; ind++ {
  1024  		gg.Nop1(gg.ExcludeFrom(base, sub...))
  1025  	}
  1026  }
  1027  
  1028  func TestIntersect(t *testing.T) {
  1029  	defer gtest.Catch(t)
  1030  
  1031  	type Type = []int
  1032  
  1033  	gtest.Zero(gg.Intersect(Type(nil), Type(nil)))
  1034  	gtest.Zero(gg.Intersect(Type{}, Type(nil)))
  1035  	gtest.Zero(gg.Intersect(Type(nil), Type{}))
  1036  	gtest.Zero(gg.Intersect(Type{}, Type{}))
  1037  	gtest.Zero(gg.Intersect(Type{10, 20, 30}, Type(nil)))
  1038  	gtest.Zero(gg.Intersect(Type(nil), Type{10, 20, 30}))
  1039  	gtest.Zero(gg.Intersect(Type{10}, Type{20}))
  1040  	gtest.Zero(gg.Intersect(Type{10, 20}, Type{30, 40}))
  1041  
  1042  	gtest.Equal(gg.Intersect(Type{10, 20, 30}, Type{10}), Type{10})
  1043  	gtest.Equal(gg.Intersect(Type{10, 20, 30}, Type{10, 20}), Type{10, 20})
  1044  	gtest.Equal(gg.Intersect(Type{10, 20, 30}, Type{10, 20, 30}), Type{10, 20, 30})
  1045  
  1046  	gtest.Equal(gg.Intersect(Type{10}, Type{10, 20, 30}), Type{10})
  1047  	gtest.Equal(gg.Intersect(Type{10, 20}, Type{10, 20, 30}), Type{10, 20})
  1048  	gtest.Equal(gg.Intersect(Type{10, 20, 30}, Type{10, 20, 30}), Type{10, 20, 30})
  1049  
  1050  	gtest.Equal(gg.Intersect(Type{10, 20}, Type{-10, 20, 30}), Type{20})
  1051  	gtest.Equal(gg.Intersect(Type{10, 20, 30}, Type{-10, 20, 30, 40}), Type{20, 30})
  1052  }
  1053  
  1054  func TestUnion(t *testing.T) {
  1055  	defer gtest.Catch(t)
  1056  
  1057  	type Elem = int
  1058  	type Slice = []Elem
  1059  
  1060  	gtest.Zero(gg.Union[Slice]())
  1061  	gtest.Zero(gg.Union[Slice](nil))
  1062  	gtest.Zero(gg.Union[Slice](nil, nil))
  1063  	gtest.Zero(gg.Union[Slice](nil, nil, Slice{}, nil, Slice{}))
  1064  
  1065  	// Special case: if the arguments have exactly one non-empty slice, return it
  1066  	// as-is, even if it contains dupes.
  1067  	gtest.Equal(gg.Union(Slice{10}), Slice{10})
  1068  	gtest.Equal(gg.Union(Slice{10, 10}), Slice{10, 10})
  1069  	gtest.Equal(gg.Union(nil, Slice{10, 10}), Slice{10, 10})
  1070  	gtest.Equal(gg.Union(Slice{10, 10}, nil), Slice{10, 10})
  1071  	gtest.Equal(gg.Union(nil, Slice{10, 10}, nil), Slice{10, 10})
  1072  
  1073  	gtest.Equal(gg.Union(Slice{10}, Slice{10}), Slice{10})
  1074  	gtest.Equal(gg.Union(Slice{10, 20}, Slice{10}), Slice{10, 20})
  1075  	gtest.Equal(gg.Union(Slice{10, 20}, Slice{10, 20}), Slice{10, 20})
  1076  	gtest.Equal(gg.Union(Slice{10, 20}, Slice{20, 10}), Slice{10, 20})
  1077  	gtest.Equal(gg.Union(Slice{10, 20}, Slice{20, 10, 30}), Slice{10, 20, 30})
  1078  	gtest.Equal(gg.Union(Slice{10, 20}, Slice{20, 10}, Slice{30, 20, 10}), Slice{10, 20, 30})
  1079  	gtest.Equal(gg.Union(Slice{}, Slice{20, 10}, Slice{30, 20, 10}), Slice{20, 10, 30})
  1080  }
  1081  
  1082  func BenchmarkUnion(b *testing.B) {
  1083  	src := [][]int{{10, 20}, {30, 40}, {50, 60}}
  1084  
  1085  	for ind := 0; ind < b.N; ind++ {
  1086  		gg.Nop1(gg.Union(src...))
  1087  	}
  1088  }
  1089  
  1090  func TestUniq(t *testing.T) {
  1091  	defer gtest.Catch(t)
  1092  
  1093  	testUniqCommon(gg.Uniq[[]int])
  1094  }
  1095  
  1096  func testUniqCommon(fun func([]int) []int) {
  1097  	type Slice = []int
  1098  
  1099  	gtest.Zero(fun(Slice(nil)))
  1100  	gtest.Zero(fun(Slice{}))
  1101  
  1102  	gtest.Equal(fun(Slice{10}), Slice{10})
  1103  	gtest.Equal(fun(Slice{10, 10}), Slice{10})
  1104  	gtest.Equal(fun(Slice{10, 10, 10}), Slice{10})
  1105  	gtest.Equal(fun(Slice{10, 10, 10, 20}), Slice{10, 20})
  1106  	gtest.Equal(fun(Slice{10, 10, 10, 20, 20}), Slice{10, 20})
  1107  	gtest.Equal(fun(Slice{10, 20, 20, 10}), Slice{10, 20})
  1108  	gtest.Equal(fun(Slice{30, 10, 20, 20, 10, 30}), Slice{30, 10, 20})
  1109  }
  1110  
  1111  func TestUniqBy(t *testing.T) {
  1112  	defer gtest.Catch(t)
  1113  
  1114  	type Elem = int
  1115  	type Slice = []Elem
  1116  
  1117  	testUniqCommon(func(src Slice) Slice {
  1118  		return gg.UniqBy(src, gg.Id1[Elem])
  1119  	})
  1120  
  1121  	testUniqCommon(func(src Slice) Slice {
  1122  		return gg.UniqBy(src, gg.String[Elem])
  1123  	})
  1124  
  1125  	gtest.Zero(gg.UniqBy[Slice, Elem, string](Slice(nil), nil))
  1126  	gtest.Zero(gg.UniqBy[Slice, Elem, string](Slice{}, nil))
  1127  	gtest.Zero(gg.UniqBy[Slice, Elem, string](Slice{10}, nil))
  1128  	gtest.Zero(gg.UniqBy[Slice, Elem, string](Slice{10, 20}, nil))
  1129  	gtest.Zero(gg.UniqBy[Slice, Elem, string](Slice{10, 20, 30}, nil))
  1130  
  1131  	gtest.Equal(
  1132  		gg.UniqBy(
  1133  			Slice{10, 20, 10, 30, 10},
  1134  			func(Elem) struct{} { return struct{}{} },
  1135  		),
  1136  		Slice{10},
  1137  	)
  1138  
  1139  	gtest.Equal(
  1140  		gg.UniqBy(
  1141  			Slice{20, 10, 20, 30, 30},
  1142  			func(Elem) struct{} { return struct{}{} },
  1143  		),
  1144  		Slice{20},
  1145  	)
  1146  }
  1147  
  1148  func TestHas(t *testing.T) {
  1149  	defer gtest.Catch(t)
  1150  
  1151  	type Type = []int
  1152  
  1153  	gtest.False(gg.Has(Type(nil), 0))
  1154  	gtest.False(gg.Has(Type(nil), 10))
  1155  	gtest.False(gg.Has(Type{}, 0))
  1156  	gtest.False(gg.Has(Type{}, 10))
  1157  	gtest.False(gg.Has(Type{10, 20, 30}, 40))
  1158  	gtest.False(gg.Has(Type{10, 20, 30}, 0))
  1159  	gtest.False(gg.Has(Type{0, 10, 0, 20, 30}, 40))
  1160  
  1161  	gtest.True(gg.Has(Type{10, 20, 30}, 10))
  1162  	gtest.True(gg.Has(Type{10, 20, 30}, 20))
  1163  	gtest.True(gg.Has(Type{10, 20, 30}, 30))
  1164  	gtest.True(gg.Has(Type{0, 10, 0, 20}, 0))
  1165  }
  1166  
  1167  func BenchmarkHas(b *testing.B) {
  1168  	defer gtest.Catch(b)
  1169  
  1170  	tar := gg.Times(128, gg.Inc[int])
  1171  	b.ResetTimer()
  1172  
  1173  	for ind := 0; ind < b.N; ind++ {
  1174  		gg.Nop1(gg.Has(tar, 256))
  1175  	}
  1176  }
  1177  
  1178  func TestHasEvery(t *testing.T) {
  1179  	defer gtest.Catch(t)
  1180  
  1181  	type Type = []int
  1182  
  1183  	gtest.True(gg.HasEvery(Type(nil), nil))
  1184  	gtest.True(gg.HasEvery(Type(nil), Type{}))
  1185  	gtest.True(gg.HasEvery(Type{}, nil))
  1186  	gtest.True(gg.HasEvery(Type{}, Type{}))
  1187  
  1188  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{10}))
  1189  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{20}))
  1190  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{30}))
  1191  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{10, 20}))
  1192  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{20, 30}))
  1193  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{10, 30}))
  1194  	gtest.True(gg.HasEvery(Type{10, 20, 30, 40}, Type{10, 20, 30}))
  1195  
  1196  	gtest.False(gg.HasEvery(Type(nil), Type{10}))
  1197  	gtest.False(gg.HasEvery(Type{}, Type{10}))
  1198  	gtest.False(gg.HasEvery(Type{10}, Type{20}))
  1199  	gtest.False(gg.HasEvery(Type{10, 20}, Type{20, 30}))
  1200  }
  1201  
  1202  func TestHasSome(t *testing.T) {
  1203  	defer gtest.Catch(t)
  1204  
  1205  	type Type = []int
  1206  
  1207  	gtest.False(gg.HasSome(Type(nil), nil))
  1208  	gtest.False(gg.HasSome(Type(nil), Type{}))
  1209  	gtest.False(gg.HasSome(Type{}, nil))
  1210  	gtest.False(gg.HasSome(Type{}, Type{}))
  1211  
  1212  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{10}))
  1213  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{20}))
  1214  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{30}))
  1215  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{10, 20}))
  1216  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{20, 30}))
  1217  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{10, 30}))
  1218  	gtest.True(gg.HasSome(Type{10, 20, 30, 40}, Type{10, 20, 30}))
  1219  
  1220  	gtest.False(gg.HasSome(Type(nil), Type{10}))
  1221  	gtest.False(gg.HasSome(Type{}, Type{10}))
  1222  	gtest.False(gg.HasSome(Type{10}, Type{20}))
  1223  	gtest.False(gg.HasSome(Type{10, 20}, Type{}))
  1224  	gtest.False(gg.HasSome(Type{10, 20}, Type{30}))
  1225  }
  1226  
  1227  func TestHasNone(t *testing.T) {
  1228  	defer gtest.Catch(t)
  1229  
  1230  	type Type = []int
  1231  
  1232  	gtest.True(gg.HasNone(Type(nil), nil))
  1233  	gtest.True(gg.HasNone(Type(nil), Type{}))
  1234  	gtest.True(gg.HasNone(Type{}, nil))
  1235  	gtest.True(gg.HasNone(Type{}, Type{}))
  1236  
  1237  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{10}))
  1238  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{20}))
  1239  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{30}))
  1240  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{10, 20}))
  1241  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{20, 30}))
  1242  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{10, 30}))
  1243  	gtest.False(gg.HasNone(Type{10, 20, 30, 40}, Type{10, 20, 30}))
  1244  
  1245  	gtest.True(gg.HasNone(Type(nil), Type{10}))
  1246  	gtest.True(gg.HasNone(Type{}, Type{10}))
  1247  	gtest.True(gg.HasNone(Type{10}, Type{20}))
  1248  	gtest.True(gg.HasNone(Type{10, 20}, Type{}))
  1249  	gtest.True(gg.HasNone(Type{10, 20}, Type{30}))
  1250  }
  1251  
  1252  func TestSome(t *testing.T) {
  1253  	defer gtest.Catch(t)
  1254  
  1255  	type Type = []int
  1256  
  1257  	gtest.False(gg.Some(Type(nil), False1[int]))
  1258  	gtest.False(gg.Some(Type{}, False1[int]))
  1259  
  1260  	gtest.False(gg.Some(Type(nil), True1[int]))
  1261  	gtest.False(gg.Some(Type{}, True1[int]))
  1262  
  1263  	gtest.False(gg.Some(Type{10}, False1[int]))
  1264  	gtest.False(gg.Some(Type{10, 20}, False1[int]))
  1265  	gtest.False(gg.Some(Type{10, 20, 30}, False1[int]))
  1266  
  1267  	gtest.True(gg.Some(Type{10}, True1[int]))
  1268  	gtest.True(gg.Some(Type{10, 20}, True1[int]))
  1269  	gtest.True(gg.Some(Type{10, 20, 30}, True1[int]))
  1270  
  1271  	gtest.False(gg.Some(Type{10, 20, 30}, gg.IsNeg[int]))
  1272  	gtest.True(gg.Some(Type{10, 20, 30}, gg.IsPos[int]))
  1273  
  1274  	gtest.True(gg.Some(Type{-10, 10, -20, 20}, gg.IsNeg[int]))
  1275  	gtest.True(gg.Some(Type{-10, 10, -20, 20}, gg.IsPos[int]))
  1276  }
  1277  
  1278  func TestNone(t *testing.T) {
  1279  	defer gtest.Catch(t)
  1280  
  1281  	type Type = []int
  1282  
  1283  	gtest.True(gg.None(Type(nil), nil))
  1284  	gtest.True(gg.None(Type{10, 20}, nil))
  1285  
  1286  	gtest.True(gg.None(Type(nil), False1[int]))
  1287  	gtest.True(gg.None(Type{}, False1[int]))
  1288  
  1289  	gtest.True(gg.None(Type(nil), True1[int]))
  1290  	gtest.True(gg.None(Type{}, True1[int]))
  1291  
  1292  	gtest.True(gg.None(Type{10}, False1[int]))
  1293  	gtest.True(gg.None(Type{10, 20}, False1[int]))
  1294  	gtest.True(gg.None(Type{10, 20, 30}, False1[int]))
  1295  
  1296  	gtest.False(gg.None(Type{10}, True1[int]))
  1297  	gtest.False(gg.None(Type{10, 20}, True1[int]))
  1298  	gtest.False(gg.None(Type{10, 20, 30}, True1[int]))
  1299  
  1300  	gtest.True(gg.None(Type{10, 20, 30}, gg.IsNeg[int]))
  1301  	gtest.False(gg.None(Type{10, 20, 30}, gg.IsPos[int]))
  1302  
  1303  	gtest.False(gg.None(Type{-10, 10, -20, 20}, gg.IsNeg[int]))
  1304  	gtest.False(gg.None(Type{-10, 10, -20, 20}, gg.IsPos[int]))
  1305  }
  1306  
  1307  func TestEvery(t *testing.T) {
  1308  	defer gtest.Catch(t)
  1309  
  1310  	type Type = []int
  1311  
  1312  	gtest.True(gg.Every(Type(nil), False1[int]))
  1313  	gtest.True(gg.Every(Type{}, False1[int]))
  1314  
  1315  	gtest.True(gg.Every(Type(nil), True1[int]))
  1316  	gtest.True(gg.Every(Type{}, True1[int]))
  1317  
  1318  	gtest.False(gg.Every(Type{10}, False1[int]))
  1319  	gtest.False(gg.Every(Type{10, 20}, False1[int]))
  1320  	gtest.False(gg.Every(Type{10, 20, 30}, False1[int]))
  1321  
  1322  	gtest.True(gg.Every(Type{10}, True1[int]))
  1323  	gtest.True(gg.Every(Type{10, 20}, True1[int]))
  1324  	gtest.True(gg.Every(Type{10, 20, 30}, True1[int]))
  1325  
  1326  	gtest.False(gg.Every(Type{10, 20, 30}, gg.IsNeg[int]))
  1327  	gtest.True(gg.Every(Type{10, 20, 30}, gg.IsPos[int]))
  1328  
  1329  	gtest.False(gg.Every(Type{-10, 10, -20, 20}, gg.IsNeg[int]))
  1330  	gtest.False(gg.Every(Type{-10, 10, -20, 20}, gg.IsPos[int]))
  1331  }
  1332  
  1333  func TestConcat(t *testing.T) {
  1334  	defer gtest.Catch(t)
  1335  
  1336  	type Type = []int
  1337  
  1338  	gtest.Zero(gg.Concat[Type]())
  1339  	gtest.Zero(gg.Concat[Type](nil))
  1340  	gtest.Zero(gg.Concat[Type](nil, nil))
  1341  	gtest.Zero(gg.Concat[Type](nil, nil, nil))
  1342  
  1343  	gtest.Equal(gg.Concat(Type{}), Type{})
  1344  	gtest.Equal(gg.Concat(Type{}, nil), Type{})
  1345  	gtest.Equal(gg.Concat(nil, Type{}), Type{})
  1346  	gtest.Equal(gg.Concat(Type{}, Type{}), Type{})
  1347  
  1348  	gtest.Equal(gg.Concat(Type{10}, Type{}), Type{10})
  1349  	gtest.Equal(gg.Concat(Type{10, 20}, Type{}), Type{10, 20})
  1350  	gtest.Equal(gg.Concat(Type{10}, Type{20}), Type{10, 20})
  1351  	gtest.Equal(gg.Concat(Type{10}, Type{20}, Type{30}), Type{10, 20, 30})
  1352  
  1353  	gtest.Equal(
  1354  		gg.Concat(Type{10, 20}, Type{20, 30}, Type{30, 40}),
  1355  		Type{10, 20, 20, 30, 30, 40},
  1356  	)
  1357  }
  1358  
  1359  func BenchmarkConcat(b *testing.B) {
  1360  	src := [][]int{{10, 20}, {30, 40}, {50, 60}}
  1361  
  1362  	for ind := 0; ind < b.N; ind++ {
  1363  		gg.Nop1(gg.Concat(src...))
  1364  	}
  1365  }
  1366  
  1367  func TestPrimSorted(t *testing.T) {
  1368  	defer gtest.Catch(t)
  1369  
  1370  	gtest.Equal(
  1371  		gg.SortedPrim(gg.ToSlice(20, 30, 10, 40)),
  1372  		gg.ToSlice(10, 20, 30, 40),
  1373  	)
  1374  }
  1375  
  1376  func BenchmarkPrimSorted(b *testing.B) {
  1377  	for ind := 0; ind < b.N; ind++ {
  1378  		gg.Nop1(gg.SortedPrim(gg.ToSlice(20, 30, 10, 40)))
  1379  	}
  1380  }
  1381  
  1382  func TestReversed(t *testing.T) {
  1383  	defer gtest.Catch(t)
  1384  
  1385  	gtest.Equal(gg.Reversed([]int(nil)), []int(nil))
  1386  	gtest.Equal(gg.Reversed([]int{}), []int{})
  1387  	gtest.Equal(gg.Reversed([]int{10}), []int{10})
  1388  
  1389  	gtest.Equal(gg.Reversed([]int{10, 20}), []int{20, 10})
  1390  	gtest.Equal(gg.Reversed([]int{20, 10}), []int{10, 20})
  1391  
  1392  	gtest.Equal(gg.Reversed([]int{10, 20, 30}), []int{30, 20, 10})
  1393  	gtest.Equal(gg.Reversed([]int{30, 20, 10}), []int{10, 20, 30})
  1394  
  1395  	gtest.Equal(gg.Reversed([]int{10, 20, 30, 40}), []int{40, 30, 20, 10})
  1396  	gtest.Equal(gg.Reversed([]int{40, 30, 20, 10}), []int{10, 20, 30, 40})
  1397  }
  1398  
  1399  func BenchmarkReversed(b *testing.B) {
  1400  	for ind := 0; ind < b.N; ind++ {
  1401  		gg.Nop1(gg.Reversed([]int{20, 30, 10, 40}))
  1402  	}
  1403  }
  1404  
  1405  func BenchmarkTakeWhile(b *testing.B) {
  1406  	val := []int{-30, -20, -10, 0, 10, 20, 30}
  1407  
  1408  	for ind := 0; ind < b.N; ind++ {
  1409  		gg.Nop1(gg.TakeWhile(val, gg.IsNeg[int]))
  1410  	}
  1411  }
  1412  
  1413  func TestMinPrim(t *testing.T) {
  1414  	defer gtest.Catch(t)
  1415  
  1416  	gtest.Eq(gg.MinPrim[int](), 0)
  1417  	gtest.Eq(gg.MinPrim[float64](), 0.0)
  1418  	gtest.Eq(gg.MinPrim[string](), ``)
  1419  
  1420  	gtest.Eq(gg.MinPrim(-10), -10)
  1421  	gtest.Eq(gg.MinPrim(0), 0)
  1422  	gtest.Eq(gg.MinPrim(10), 10)
  1423  
  1424  	gtest.Eq(gg.MinPrim(-10.5), -10.5)
  1425  	gtest.Eq(gg.MinPrim(0.0), 0.0)
  1426  	gtest.Eq(gg.MinPrim(10.5), 10.5)
  1427  
  1428  	gtest.Eq(gg.MinPrim(`str`), `str`)
  1429  
  1430  	gtest.Eq(gg.MinPrim(-10, 0), -10)
  1431  	gtest.Eq(gg.MinPrim(0, 10), 0)
  1432  	gtest.Eq(gg.MinPrim(-10, 10), -10)
  1433  
  1434  	gtest.Eq(gg.MinPrim(``, `10`), ``)
  1435  	gtest.Eq(gg.MinPrim(`10`, ``), ``)
  1436  	gtest.Eq(gg.MinPrim(`10`, `20`), `10`)
  1437  	gtest.Eq(gg.MinPrim(`20`, `10`), `10`)
  1438  
  1439  	gtest.Eq(gg.MinPrim(-20, -10, 0), -20)
  1440  	gtest.Eq(gg.MinPrim(0, 10, 20), 0)
  1441  	gtest.Eq(gg.MinPrim(-10, 0, 10), -10)
  1442  
  1443  	gtest.Eq(gg.MinPrim(``, `20`, `10`), ``)
  1444  	gtest.Eq(gg.MinPrim(``, `10`, `20`), ``)
  1445  	gtest.Eq(gg.MinPrim(`10`, ``, `20`), ``)
  1446  	gtest.Eq(gg.MinPrim(`10`, `20`, ``), ``)
  1447  
  1448  	gtest.Eq(gg.MinPrim(`10`, `20`, `30`), `10`)
  1449  	gtest.Eq(gg.MinPrim(`20`, `10`, `30`), `10`)
  1450  	gtest.Eq(gg.MinPrim(`30`, `20`, `10`), `10`)
  1451  }
  1452  
  1453  func BenchmarkMinPrim(b *testing.B) {
  1454  	for ind := 0; ind < b.N; ind++ {
  1455  		gg.Nop1(gg.MinPrim(ind-1, ind, ind+1))
  1456  	}
  1457  }
  1458  
  1459  func TestMaxPrim(t *testing.T) {
  1460  	defer gtest.Catch(t)
  1461  
  1462  	gtest.Eq(gg.MaxPrim[int](), 0)
  1463  	gtest.Eq(gg.MaxPrim[float64](), 0.0)
  1464  	gtest.Eq(gg.MaxPrim[string](), ``)
  1465  
  1466  	gtest.Eq(gg.MaxPrim(-10), -10)
  1467  	gtest.Eq(gg.MaxPrim(0), 0)
  1468  	gtest.Eq(gg.MaxPrim(10), 10)
  1469  
  1470  	gtest.Eq(gg.MaxPrim(-10.5), -10.5)
  1471  	gtest.Eq(gg.MaxPrim(0.0), 0.0)
  1472  	gtest.Eq(gg.MaxPrim(10.5), 10.5)
  1473  
  1474  	gtest.Eq(gg.MaxPrim(`str`), `str`)
  1475  
  1476  	gtest.Eq(gg.MaxPrim(-10, 0), 0)
  1477  	gtest.Eq(gg.MaxPrim(0, 10), 10)
  1478  	gtest.Eq(gg.MaxPrim(-10, 10), 10)
  1479  
  1480  	gtest.Eq(gg.MaxPrim(``, `10`), `10`)
  1481  	gtest.Eq(gg.MaxPrim(`10`, ``), `10`)
  1482  	gtest.Eq(gg.MaxPrim(`10`, `20`), `20`)
  1483  	gtest.Eq(gg.MaxPrim(`20`, `10`), `20`)
  1484  
  1485  	gtest.Eq(gg.MaxPrim(-20, -10, 0), 0)
  1486  	gtest.Eq(gg.MaxPrim(0, 10, 20), 20)
  1487  	gtest.Eq(gg.MaxPrim(-10, 0, 10), 10)
  1488  
  1489  	gtest.Eq(gg.MaxPrim(``, `20`, `10`), `20`)
  1490  	gtest.Eq(gg.MaxPrim(``, `10`, `20`), `20`)
  1491  	gtest.Eq(gg.MaxPrim(`10`, ``, `20`), `20`)
  1492  	gtest.Eq(gg.MaxPrim(`10`, `20`, ``), `20`)
  1493  
  1494  	gtest.Eq(gg.MaxPrim(`10`, `20`, `30`), `30`)
  1495  	gtest.Eq(gg.MaxPrim(`20`, `10`, `30`), `30`)
  1496  	gtest.Eq(gg.MaxPrim(`30`, `20`, `10`), `30`)
  1497  }
  1498  
  1499  func BenchmarkMaxPrim(b *testing.B) {
  1500  	for ind := 0; ind < b.N; ind++ {
  1501  		gg.Nop1(gg.MaxPrim(ind-1, ind, ind+1))
  1502  	}
  1503  }
  1504  
  1505  func TestMin(t *testing.T) {
  1506  	defer gtest.Catch(t)
  1507  
  1508  	gtest.Eq(gg.Min[Comparer[int]](), ComparerOf(0))
  1509  	gtest.Eq(gg.Min[Comparer[float64]](), ComparerOf(0.0))
  1510  	gtest.Eq(gg.Min[Comparer[string]](), ComparerOf(``))
  1511  
  1512  	gtest.Eq(gg.Min(ComparerOf(-10)), ComparerOf(-10))
  1513  	gtest.Eq(gg.Min(ComparerOf(0)), ComparerOf(0))
  1514  	gtest.Eq(gg.Min(ComparerOf(10)), ComparerOf(10))
  1515  
  1516  	gtest.Eq(gg.Min(ComparerOf(-10.5)), ComparerOf(-10.5))
  1517  	gtest.Eq(gg.Min(ComparerOf(0.0)), ComparerOf(0.0))
  1518  	gtest.Eq(gg.Min(ComparerOf(10.5)), ComparerOf(10.5))
  1519  
  1520  	gtest.Eq(gg.Min(ComparerOf(`str`)), ComparerOf(`str`))
  1521  
  1522  	gtest.Eq(gg.Min(ComparerOf(-10), ComparerOf(0)), ComparerOf(-10))
  1523  	gtest.Eq(gg.Min(ComparerOf(0), ComparerOf(10)), ComparerOf(0))
  1524  	gtest.Eq(gg.Min(ComparerOf(-10), ComparerOf(10)), ComparerOf(-10))
  1525  
  1526  	gtest.Eq(gg.Min(ComparerOf(``), ComparerOf(`10`)), ComparerOf(``))
  1527  	gtest.Eq(gg.Min(ComparerOf(`10`), ComparerOf(``)), ComparerOf(``))
  1528  	gtest.Eq(gg.Min(ComparerOf(`10`), ComparerOf(`20`)), ComparerOf(`10`))
  1529  	gtest.Eq(gg.Min(ComparerOf(`20`), ComparerOf(`10`)), ComparerOf(`10`))
  1530  
  1531  	gtest.Eq(gg.Min(ComparerOf(-20), ComparerOf(-10), ComparerOf(0)), ComparerOf(-20))
  1532  	gtest.Eq(gg.Min(ComparerOf(0), ComparerOf(10), ComparerOf(20)), ComparerOf(0))
  1533  	gtest.Eq(gg.Min(ComparerOf(-10), ComparerOf(0), ComparerOf(10)), ComparerOf(-10))
  1534  
  1535  	gtest.Eq(gg.Min(ComparerOf(``), ComparerOf(`20`), ComparerOf(`10`)), ComparerOf(``))
  1536  	gtest.Eq(gg.Min(ComparerOf(``), ComparerOf(`10`), ComparerOf(`20`)), ComparerOf(``))
  1537  	gtest.Eq(gg.Min(ComparerOf(`10`), ComparerOf(``), ComparerOf(`20`)), ComparerOf(``))
  1538  	gtest.Eq(gg.Min(ComparerOf(`10`), ComparerOf(`20`), ComparerOf(``)), ComparerOf(``))
  1539  
  1540  	gtest.Eq(gg.Min(ComparerOf(`10`), ComparerOf(`20`), ComparerOf(`30`)), ComparerOf(`10`))
  1541  	gtest.Eq(gg.Min(ComparerOf(`20`), ComparerOf(`10`), ComparerOf(`30`)), ComparerOf(`10`))
  1542  	gtest.Eq(gg.Min(ComparerOf(`30`), ComparerOf(`20`), ComparerOf(`10`)), ComparerOf(`10`))
  1543  }
  1544  
  1545  func TestMax(t *testing.T) {
  1546  	defer gtest.Catch(t)
  1547  
  1548  	gtest.Eq(gg.Max[Comparer[int]](), ComparerOf(0))
  1549  	gtest.Eq(gg.Max[Comparer[float64]](), ComparerOf(0.0))
  1550  	gtest.Eq(gg.Max[Comparer[string]](), ComparerOf(``))
  1551  
  1552  	gtest.Eq(gg.Max(ComparerOf(-10)), ComparerOf(-10))
  1553  	gtest.Eq(gg.Max(ComparerOf(0)), ComparerOf(0))
  1554  	gtest.Eq(gg.Max(ComparerOf(10)), ComparerOf(10))
  1555  
  1556  	gtest.Eq(gg.Max(ComparerOf(-10.5)), ComparerOf(-10.5))
  1557  	gtest.Eq(gg.Max(ComparerOf(0.0)), ComparerOf(0.0))
  1558  	gtest.Eq(gg.Max(ComparerOf(10.5)), ComparerOf(10.5))
  1559  
  1560  	gtest.Eq(gg.Max(ComparerOf(`str`)), ComparerOf(`str`))
  1561  
  1562  	gtest.Eq(gg.Max(ComparerOf(-10), ComparerOf(0)), ComparerOf(0))
  1563  	gtest.Eq(gg.Max(ComparerOf(0), ComparerOf(10)), ComparerOf(10))
  1564  	gtest.Eq(gg.Max(ComparerOf(-10), ComparerOf(10)), ComparerOf(10))
  1565  
  1566  	gtest.Eq(gg.Max(ComparerOf(``), ComparerOf(`10`)), ComparerOf(`10`))
  1567  	gtest.Eq(gg.Max(ComparerOf(`10`), ComparerOf(``)), ComparerOf(`10`))
  1568  	gtest.Eq(gg.Max(ComparerOf(`10`), ComparerOf(`20`)), ComparerOf(`20`))
  1569  	gtest.Eq(gg.Max(ComparerOf(`20`), ComparerOf(`10`)), ComparerOf(`20`))
  1570  
  1571  	gtest.Eq(gg.Max(ComparerOf(-20), ComparerOf(-10), ComparerOf(0)), ComparerOf(0))
  1572  	gtest.Eq(gg.Max(ComparerOf(0), ComparerOf(10), ComparerOf(20)), ComparerOf(20))
  1573  	gtest.Eq(gg.Max(ComparerOf(-10), ComparerOf(0), ComparerOf(10)), ComparerOf(10))
  1574  
  1575  	gtest.Eq(gg.Max(ComparerOf(``), ComparerOf(`20`), ComparerOf(`10`)), ComparerOf(`20`))
  1576  	gtest.Eq(gg.Max(ComparerOf(``), ComparerOf(`10`), ComparerOf(`20`)), ComparerOf(`20`))
  1577  	gtest.Eq(gg.Max(ComparerOf(`10`), ComparerOf(``), ComparerOf(`20`)), ComparerOf(`20`))
  1578  	gtest.Eq(gg.Max(ComparerOf(`10`), ComparerOf(`20`), ComparerOf(``)), ComparerOf(`20`))
  1579  
  1580  	gtest.Eq(gg.Max(ComparerOf(`10`), ComparerOf(`20`), ComparerOf(`30`)), ComparerOf(`30`))
  1581  	gtest.Eq(gg.Max(ComparerOf(`20`), ComparerOf(`10`), ComparerOf(`30`)), ComparerOf(`30`))
  1582  	gtest.Eq(gg.Max(ComparerOf(`30`), ComparerOf(`20`), ComparerOf(`10`)), ComparerOf(`30`))
  1583  }
  1584  
  1585  func TestMinPrimBy(t *testing.T) {
  1586  	defer gtest.Catch(t)
  1587  
  1588  	type Out = int
  1589  	type Src = Comparer[Out]
  1590  	var fun = Src.Get
  1591  
  1592  	gtest.Zero(gg.MinPrimBy[Src, Out](nil, nil))
  1593  	gtest.Zero(gg.MinPrimBy[Src, Out]([]Src{}, nil))
  1594  	gtest.Zero(gg.MinPrimBy[Src, Out]([]Src{{10}}, nil))
  1595  	gtest.Zero(gg.MinPrimBy[Src, Out]([]Src{{10}, {20}}, nil))
  1596  
  1597  	gtest.Zero(gg.MinPrimBy[Src, Out](nil, fun))
  1598  	gtest.Zero(gg.MinPrimBy([]Src{}, fun))
  1599  
  1600  	gtest.Eq(gg.MinPrimBy([]Src{{-10}}, fun), -10)
  1601  	gtest.Eq(gg.MinPrimBy([]Src{{0}}, fun), 0)
  1602  	gtest.Eq(gg.MinPrimBy([]Src{{10}}, fun), 10)
  1603  
  1604  	gtest.Eq(gg.MinPrimBy([]Src{{0}, {-10}}, fun), -10)
  1605  	gtest.Eq(gg.MinPrimBy([]Src{{-10}, {0}}, fun), -10)
  1606  	gtest.Eq(gg.MinPrimBy([]Src{{0}, {10}}, fun), 0)
  1607  	gtest.Eq(gg.MinPrimBy([]Src{{10}, {0}}, fun), 0)
  1608  	gtest.Eq(gg.MinPrimBy([]Src{{-10}, {10}}, fun), -10)
  1609  	gtest.Eq(gg.MinPrimBy([]Src{{10}, {-10}}, fun), -10)
  1610  
  1611  	gtest.Eq(gg.MinPrimBy([]Src{{-10}, {-20}, {0}}, fun), -20)
  1612  	gtest.Eq(gg.MinPrimBy([]Src{{0}, {-10}, {10}}, fun), -10)
  1613  	gtest.Eq(gg.MinPrimBy([]Src{{10}, {0}, {20}}, fun), 0)
  1614  }
  1615  
  1616  func TestMaxPrimBy(t *testing.T) {
  1617  	defer gtest.Catch(t)
  1618  
  1619  	type Out = int
  1620  	type Src = Comparer[Out]
  1621  	var fun = Src.Get
  1622  
  1623  	gtest.Zero(gg.MaxPrimBy[Src, Out](nil, nil))
  1624  	gtest.Zero(gg.MaxPrimBy[Src, Out]([]Src{}, nil))
  1625  	gtest.Zero(gg.MaxPrimBy[Src, Out]([]Src{{10}}, nil))
  1626  	gtest.Zero(gg.MaxPrimBy[Src, Out]([]Src{{10}, {20}}, nil))
  1627  
  1628  	gtest.Zero(gg.MaxPrimBy[Src, Out](nil, fun))
  1629  	gtest.Zero(gg.MaxPrimBy([]Src{}, fun))
  1630  
  1631  	gtest.Eq(gg.MaxPrimBy([]Src{{-10}}, fun), -10)
  1632  	gtest.Eq(gg.MaxPrimBy([]Src{{0}}, fun), 0)
  1633  	gtest.Eq(gg.MaxPrimBy([]Src{{10}}, fun), 10)
  1634  
  1635  	gtest.Eq(gg.MaxPrimBy([]Src{{0}, {-10}}, fun), 0)
  1636  	gtest.Eq(gg.MaxPrimBy([]Src{{-10}, {0}}, fun), 0)
  1637  	gtest.Eq(gg.MaxPrimBy([]Src{{0}, {10}}, fun), 10)
  1638  	gtest.Eq(gg.MaxPrimBy([]Src{{10}, {0}}, fun), 10)
  1639  	gtest.Eq(gg.MaxPrimBy([]Src{{-10}, {10}}, fun), 10)
  1640  	gtest.Eq(gg.MaxPrimBy([]Src{{10}, {-10}}, fun), 10)
  1641  
  1642  	gtest.Eq(gg.MaxPrimBy([]Src{{-10}, {0}, {-20}}, fun), 0)
  1643  	gtest.Eq(gg.MaxPrimBy([]Src{{0}, {10}, {-10}}, fun), 10)
  1644  	gtest.Eq(gg.MaxPrimBy([]Src{{10}, {20}, {0}}, fun), 20)
  1645  }
  1646  
  1647  func TestMinBy(t *testing.T) {
  1648  	defer gtest.Catch(t)
  1649  
  1650  	type Src = int
  1651  	type Out = Comparer[Src]
  1652  	var fun = ComparerOf[Src]
  1653  
  1654  	gtest.Zero(gg.MinBy[Src, Out](nil, nil))
  1655  	gtest.Zero(gg.MinBy[Src, Out]([]Src{}, nil))
  1656  	gtest.Zero(gg.MinBy[Src, Out]([]Src{10}, nil))
  1657  	gtest.Zero(gg.MinBy[Src, Out]([]Src{10, 20}, nil))
  1658  
  1659  	gtest.Zero(gg.MinBy[Src, Out](nil, fun))
  1660  	gtest.Zero(gg.MinBy([]Src{}, fun))
  1661  
  1662  	gtest.Eq(gg.MinBy([]Src{-10}, fun), Out{-10})
  1663  	gtest.Eq(gg.MinBy([]Src{0}, fun), Out{0})
  1664  	gtest.Eq(gg.MinBy([]Src{10}, fun), Out{10})
  1665  
  1666  	gtest.Eq(gg.MinBy([]Src{0, -10}, fun), Out{-10})
  1667  	gtest.Eq(gg.MinBy([]Src{-10, 0}, fun), Out{-10})
  1668  	gtest.Eq(gg.MinBy([]Src{0, 10}, fun), Out{0})
  1669  	gtest.Eq(gg.MinBy([]Src{10, 0}, fun), Out{0})
  1670  	gtest.Eq(gg.MinBy([]Src{-10, 10}, fun), Out{-10})
  1671  	gtest.Eq(gg.MinBy([]Src{10, -10}, fun), Out{-10})
  1672  
  1673  	gtest.Eq(gg.MinBy([]Src{-10, -20, 0}, fun), Out{-20})
  1674  	gtest.Eq(gg.MinBy([]Src{0, -10, 10}, fun), Out{-10})
  1675  	gtest.Eq(gg.MinBy([]Src{10, 0, 20}, fun), Out{0})
  1676  }
  1677  
  1678  func TestMaxBy(t *testing.T) {
  1679  	defer gtest.Catch(t)
  1680  
  1681  	type Src = int
  1682  	type Out = Comparer[Src]
  1683  	var fun = ComparerOf[Src]
  1684  
  1685  	gtest.Zero(gg.MaxBy[Src, Out](nil, nil))
  1686  	gtest.Zero(gg.MaxBy[Src, Out]([]Src{}, nil))
  1687  	gtest.Zero(gg.MaxBy[Src, Out]([]Src{10}, nil))
  1688  	gtest.Zero(gg.MaxBy[Src, Out]([]Src{10, 20}, nil))
  1689  
  1690  	gtest.Zero(gg.MaxBy[Src, Out](nil, fun))
  1691  	gtest.Zero(gg.MaxBy([]Src{}, fun))
  1692  
  1693  	gtest.Eq(gg.MaxBy([]Src{-10}, fun), Out{-10})
  1694  	gtest.Eq(gg.MaxBy([]Src{0}, fun), Out{0})
  1695  	gtest.Eq(gg.MaxBy([]Src{10}, fun), Out{10})
  1696  
  1697  	gtest.Eq(gg.MaxBy([]Src{0, -10}, fun), Out{0})
  1698  	gtest.Eq(gg.MaxBy([]Src{-10, 0}, fun), Out{0})
  1699  	gtest.Eq(gg.MaxBy([]Src{0, 10}, fun), Out{10})
  1700  	gtest.Eq(gg.MaxBy([]Src{10, 0}, fun), Out{10})
  1701  	gtest.Eq(gg.MaxBy([]Src{-10, 10}, fun), Out{10})
  1702  	gtest.Eq(gg.MaxBy([]Src{10, -10}, fun), Out{10})
  1703  
  1704  	gtest.Eq(gg.MaxBy([]Src{-10, 0, -20}, fun), Out{0})
  1705  	gtest.Eq(gg.MaxBy([]Src{0, 10, -10}, fun), Out{10})
  1706  	gtest.Eq(gg.MaxBy([]Src{10, 20, 0}, fun), Out{20})
  1707  }
  1708  
  1709  func TestSum(t *testing.T) {
  1710  	defer gtest.Catch(t)
  1711  
  1712  	type Out = int
  1713  	type Src = Comparer[Out]
  1714  	var fun = Src.Get
  1715  
  1716  	gtest.Zero(gg.Sum[Src, Out](nil, nil))
  1717  	gtest.Zero(gg.Sum[Src, Out]([]Src{}, nil))
  1718  	gtest.Zero(gg.Sum[Src, Out]([]Src{{10}}, nil))
  1719  	gtest.Zero(gg.Sum[Src, Out]([]Src{{10}, {20}}, nil))
  1720  
  1721  	gtest.Zero(gg.Sum[Src, Out](nil, fun))
  1722  	gtest.Zero(gg.Sum([]Src{}, fun))
  1723  
  1724  	gtest.Eq(gg.Sum([]Src{{-10}}, fun), -10)
  1725  	gtest.Eq(gg.Sum([]Src{{0}}, fun), 0)
  1726  	gtest.Eq(gg.Sum([]Src{{10}}, fun), 10)
  1727  
  1728  	gtest.Eq(gg.Sum([]Src{{0}, {-10}}, fun), -10)
  1729  	gtest.Eq(gg.Sum([]Src{{-10}, {0}}, fun), -10)
  1730  	gtest.Eq(gg.Sum([]Src{{0}, {10}}, fun), 10)
  1731  	gtest.Eq(gg.Sum([]Src{{10}, {0}}, fun), 10)
  1732  	gtest.Eq(gg.Sum([]Src{{-10}, {20}}, fun), 10)
  1733  	gtest.Eq(gg.Sum([]Src{{20}, {-10}}, fun), 10)
  1734  	gtest.Eq(gg.Sum([]Src{{10}, {20}}, fun), 30)
  1735  	gtest.Eq(gg.Sum([]Src{{20}, {10}}, fun), 30)
  1736  
  1737  	gtest.Eq(gg.Sum([]Src{{-10}, {-20}, {0}}, fun), -30)
  1738  	gtest.Eq(gg.Sum([]Src{{0}, {-10}, {20}}, fun), 10)
  1739  	gtest.Eq(gg.Sum([]Src{{10}, {0}, {20}}, fun), 30)
  1740  }
  1741  
  1742  func TestCounts(t *testing.T) {
  1743  	defer gtest.Catch(t)
  1744  
  1745  	type Key = string
  1746  	type Val = byte
  1747  	type Src = []Val
  1748  	type Tar = map[Key]int
  1749  
  1750  	gtest.Zero(gg.Counts[Src, Key](Src(nil), nil))
  1751  	gtest.Zero(gg.Counts[Src, Key](Src{10}, nil))
  1752  	gtest.Zero(gg.Counts[Src, Key](Src{10, 20}, nil))
  1753  
  1754  	alwaysSame := func(Val) Key { return `key` }
  1755  
  1756  	gtest.Equal(gg.Counts(Src{}, alwaysSame), Tar{})
  1757  	gtest.Equal(gg.Counts(Src{10}, alwaysSame), Tar{`key`: 1})
  1758  	gtest.Equal(gg.Counts(Src{10, 20}, alwaysSame), Tar{`key`: 2})
  1759  	gtest.Equal(gg.Counts(Src{10, 20, 30}, alwaysSame), Tar{`key`: 3})
  1760  
  1761  	gtest.Equal(gg.Counts(Src{}, gg.String[Val]), Tar{})
  1762  	gtest.Equal(gg.Counts(Src{10}, gg.String[Val]), Tar{`10`: 1})
  1763  	gtest.Equal(gg.Counts(Src{10, 20}, gg.String[Val]), Tar{`10`: 1, `20`: 1})
  1764  	gtest.Equal(gg.Counts(Src{10, 20, 30}, gg.String[Val]), Tar{`10`: 1, `20`: 1, `30`: 1})
  1765  }