// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file shows some examples of type-parameterized functions.

package p

// Reverse is a generic function that takes a []T argument and
// reverses that slice in place.
func Reverse[T any](list []T) {
	i := 0
	j := len(list)-1
	for i < j {
		list[i], list[j] = list[j], list[i]
		i++
		j--
	}
}

func _() {
	// Reverse can be called with an explicit type argument.
	Reverse[int](nil)
	Reverse[string]([]string{"foo", "bar"})
	Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})

	// Since the type parameter is used for an incoming argument,
	// it can be inferred from the provided argument's type.
	Reverse([]string{"foo", "bar"})
	Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})

	// But the incoming argument must have a type, even if it's a
	// default type. An untyped nil won't work.
	// Reverse(nil) // this won't type-check

	// A typed nil will work, though.
	Reverse([]int(nil))
}

// Certain functions, such as the built-in `new` could be written using
// type parameters.
func new[T any]() *T {
	var x T
	return &x
}

// When calling our own `new`, we need to pass the type parameter
// explicitly since there is no (value) argument from which the
// result type could be inferred. We don't try to infer the
// result type from the assignment to keep things simple and
// easy to understand.
var _ = new[int]()
var _ *float64 = new[float64]() // the result type is indeed *float64

// A function may have multiple type parameters, of course.
func foo[A, B, C any](a A, b []B, c *C) B {
	// do something here
	return b[0]
}

// As before, we can pass type parameters explicitly.
var s = foo[int, string, float64](1, []string{"first"}, new[float64]())

// Or we can use type inference.
var _ float64 = foo(42, []float64{1.0}, &s)

// Type inference works in a straight-forward manner even
// for variadic functions.
func variadic[A, B any](A, B, ...B) int

// var _ = variadic(1) // ERROR not enough arguments
var _ = variadic(1, 2.3)
var _ = variadic(1, 2.3, 3.4, 4.5)
var _ = variadic[int, float64](1, 2.3, 3.4, 4)

// Type inference also works in recursive function calls where
// the inferred type is the type parameter of the caller.
func f1[T any](x T) {
	f1(x)
}

func f2a[T any](x, y T) {
	f2a(x, y)
}

func f2b[T any](x, y T) {
	f2b(y, x)
}

func g2a[P, Q any](x P, y Q) {
	g2a(x, y)
}

func g2b[P, Q any](x P, y Q) {
	g2b(y, x)
}

// Here's an example of a recursive function call with variadic
// arguments and type inference inferring the type parameter of
// the caller (i.e., itself).
func max[T interface{ type int }](x ...T) T {
	var x0 T
	if len(x) > 0 {
		x0 = x[0]
	}
	if len(x) > 1 {
		x1 := max(x[1:]...)
		if x1 > x0 {
			return x1
		}
	}
	return x0
}

// When inferring channel types, the channel direction is ignored
// for the purpose of type inference. Once the type has been in-
// fered, the usual parameter passing rules are applied.
// Thus even if a type can be inferred successfully, the function
// call may not be valid.

func fboth[T any](chan T)
func frecv[T any](<-chan T)
func fsend[T any](chan<- T)

func _() {
	var both chan int
	var recv <-chan int
	var send chan<-int

	fboth(both)
	fboth(recv /* ERROR cannot use */ )
	fboth(send /* ERROR cannot use */ )

	frecv(both)
	frecv(recv)
	frecv(send /* ERROR cannot use */ )

	fsend(both)
	fsend(recv /* ERROR cannot use */)
	fsend(send)
}

func ffboth[T any](func(chan T))
func ffrecv[T any](func(<-chan T))
func ffsend[T any](func(chan<- T))

func _() {
	var both func(chan int)
	var recv func(<-chan int)
	var send func(chan<- int)

	ffboth(both)
	ffboth(recv /* ERROR cannot use */ )
	ffboth(send /* ERROR cannot use */ )

	ffrecv(both /* ERROR cannot use */ )
	ffrecv(recv)
	ffrecv(send /* ERROR cannot use */ )

	ffsend(both /* ERROR cannot use */ )
	ffsend(recv /* ERROR cannot use */ )
	ffsend(send)
}

// When inferring elements of unnamed composite parameter types,
// if the arguments are defined types, use their underlying types.
// Even though the matching types are not exactly structurally the
// same (one is a type literal, the other a named type), because
// assignment is permitted, parameter passing is permitted as well,
// so type inference should be able to handle these cases well.

func g1[T any]([]T)
func g2[T any]([]T, T)
func g3[T any](*T, ...T)

func _() {
	type intSlize []int
	g1([]int{})
	g1(intSlize{})
	g2(nil, 0)

	type myString string
	var s1 string
	g3(nil, "1", myString("2"), "3")
	g3(&s1, "1", myString /* ERROR does not match */ ("2"), "3")

	type myStruct struct{x int}
	var s2 myStruct
	g3(nil, struct{x int}{}, myStruct{})
	g3(&s2, struct{x int}{}, myStruct{})
	g3(nil, myStruct{}, struct{x int}{})
	g3(&s2, myStruct{}, struct{x int}{})
}

// Here's a realistic example.

func append[T any](s []T, t ...T) []T

func _() {
	var f func()
	type Funcs []func()
	var funcs Funcs
	_ = append(funcs, f)
}

// Generic type declarations cannot have empty type parameter lists
// (that would indicate a slice type). Thus, generic functions cannot
// have empty type parameter lists, either. This is a syntax error.

func h[] /* ERROR empty type parameter list */ ()

func _() {
	h /* ERROR cannot index */ [] /* ERROR operand */ ()
}
