diff --git a/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 b/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 index 456d9222fe..d22a094ad9 100644 --- a/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 +++ b/src/cmd/go2go/testdata/go2path/src/slices/slices.go2 @@ -93,3 +93,33 @@ func Min(type Elem contracts.Ordered)(s []Elem) Elem { } return Reduce(s[1:], s[0], alg.Min(Elem)) } + +// Append adds values to the end of a slice, returning a new slice. +// This is like the predeclared append function; it's an example +// of how to write it using generics. We used to write code like +// this before append was added to the language, but we had to write +// a separate copy for each type. +func Append(type T)(s []T, t ...T) []T { + lens := len(s) + tot := lens + len(t) + if tot <= cap(s) { + s = s[:tot] + } else { + news := make([]T, tot, tot + tot/2) + Copy(news, s) + s = news + } + Copy(s[lens:tot], t) + return s +} + +// Copy copies values from t to s, stopping when either slice is full, +// returning the number of values copied. This is like the predeclared +// copy function; it's an example of how to write it using generics. +func Copy(type T)(s, t []T) int { + i := 0 + for ; i < len(s) && i < len(t); i++ { + s[i] = t[i] + } + return i +} diff --git a/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 b/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 index a64427a6ec..0e4b57aaa5 100644 --- a/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 +++ b/src/cmd/go2go/testdata/go2path/src/slices/slices_test.go2 @@ -141,3 +141,24 @@ func TestMin(t *testing.T) { t.Errorf("Min(%v) = %q, want %q", s2[:0], got, want) } } + +func TestAppend(t *testing.T) { + s := []int{1, 2, 3} + s = Append(s, 4, 5, 6) + want := []int{1, 2, 3, 4, 5, 6} + if !Equal(s, want) { + t.Errorf("after Append got %v, want %v", s, want) + } +} + +func TestCopy(t *testing.T) { + s1 := []int{1, 2, 3} + s2 := []int{4, 5} + if got := Copy(s1, s2); got != 2 { + t.Errorf("Copy returned %d, want 2", got) + } + want := []int{4, 5, 3} + if !Equal(s1, want) { + t.Errorf("after Copy got %v, want %v", s1, want) + } +}