Vendor main dependencies.

This commit is contained in:
Timo Reimann 2017-02-07 22:33:23 +01:00
parent 49a09ab7dd
commit dd5e3fba01
2738 changed files with 1045689 additions and 0 deletions

13
vendor/github.com/BurntSushi/ty/COPYING generated vendored Normal file
View file

@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

22
vendor/github.com/BurntSushi/ty/doc.go generated vendored Normal file
View file

@ -0,0 +1,22 @@
/*
Package ty provides utilities for writing type parametric functions with run
time type safety.
This package contains two sub-packages `fun` and `data` which define some
potentially useful functions and abstractions using the type checker in
this package.
Requirements
Go tip (or 1.1 when it's released) is required. This package will not work
with Go 1.0.x or earlier.
The very foundation of this package only recently became possible with the
addition of 3 new functions in the standard library `reflect` package:
SliceOf, MapOf and ChanOf. In particular, it provides the ability to
dynamically construct types at run time from component types.
Further extensions to this package can be made if similar functions are added
for structs and functions(?).
*/
package ty

84
vendor/github.com/BurntSushi/ty/fun/chan.go generated vendored Normal file
View file

@ -0,0 +1,84 @@
package fun
import (
"reflect"
"github.com/BurntSushi/ty"
)
// AsyncChan has a parametric type:
//
// func AsyncChan(chan A) (send chan<- A, recv <-chan A)
//
// AsyncChan provides a channel abstraction without a fixed size buffer.
// The input should be a pointer to a channel that has a type without a
// direction, e.g., `new(chan int)`. Two new channels are returned: `send` and
// `recv`. The caller must send data on the `send` channel and receive data on
// the `recv` channel.
//
// Implementation is inspired by Kyle Lemons' work:
// https://github.com/kylelemons/iq/blob/master/iq_slice.go
func AsyncChan(baseChan interface{}) (send, recv interface{}) {
chk := ty.Check(
new(func(*chan ty.A) (chan ty.A, chan ty.A)),
baseChan)
// We don't care about the baseChan---it is only used to construct
// the return types.
tsend, trecv := chk.Returns[0], chk.Returns[1]
buf := make([]reflect.Value, 0, 10)
rsend := reflect.MakeChan(tsend, 0)
rrecv := reflect.MakeChan(trecv, 0)
go func() {
defer rrecv.Close()
BUFLOOP:
for {
if len(buf) == 0 {
rv, ok := rsend.Recv()
if !ok {
break BUFLOOP
}
buf = append(buf, rv)
}
cases := []reflect.SelectCase{
// case v, ok := <-send
{
Dir: reflect.SelectRecv,
Chan: rsend,
},
// case recv <- buf[0]
{
Dir: reflect.SelectSend,
Chan: rrecv,
Send: buf[0],
},
}
choice, rval, rok := reflect.Select(cases)
switch choice {
case 0:
// case v, ok := <-send
if !rok {
break BUFLOOP
}
buf = append(buf, rval)
case 1:
// case recv <- buf[0]
buf = buf[1:]
default:
panic("bug")
}
}
for _, rv := range buf {
rrecv.Send(rv)
}
}()
// Create the directional channel types.
tsDir := reflect.ChanOf(reflect.SendDir, tsend.Elem())
trDir := reflect.ChanOf(reflect.RecvDir, trecv.Elem())
return rsend.Convert(tsDir).Interface(), rrecv.Convert(trDir).Interface()
}

118
vendor/github.com/BurntSushi/ty/fun/doc.go generated vendored Normal file
View file

@ -0,0 +1,118 @@
/*
Package fun provides type parametric utility functions for lists, sets,
channels and maps.
The central contribution of this package is a set of functions that operate
on values without depending on their types while maintaining type safety at
run time using the `reflect` package.
There are two primary concerns when deciding whether to use this package
or not: the loss of compile time type safety and performance. In particular,
with regard to performance, most functions here are much slower than their
built-in counter parts. However, there are a couple where the overhead of
reflection is relatively insignificant: AsyncChan and ParMap.
In terms of code structure and organization, the price is mostly paid inside
of the package due to the annoyances of operating with `reflect`. The caller
usually only has one obligation other than to provide values consistent with
the type of the function: type assert the result to the desired type.
When the caller provides values that are inconsistent with the parametric type
of the function, the function will panic with a `TypeError`. (Either because
the types cannot be unified or because they cannot be constructed due to
limitations of the `reflect` package. See the `github.com/BurntSushi/ty`
package for more details.)
Requirements
Go tip (or 1.1 when it's released) is required. This package will not work
with Go 1.0.x or earlier.
The very foundation of this package only recently became possible with the
addition of 3 new functions in the standard library `reflect` package:
SliceOf, MapOf and ChanOf. In particular, it provides the ability to
dynamically construct types at run time from component types.
Further extensions to this package can be made if similar functions are added
for structs and functions(?).
Examples
Squaring each integer in a slice:
square := func(x int) int { return x * x }
nums := []int{1, 2, 3, 4, 5}
squares := Map(square, nums).([]int)
Reversing any slice:
slice := []string{"a", "b", "c"}
reversed := Reverse(slice).([]string)
Sorting any slice:
// Sort a slice of structs with first class functions.
type Album struct {
Title string
Year int
}
albums := []Album{
{"Born to Run", 1975},
{"WIESS", 1973},
{"Darkness", 1978},
{"Greetings", 1973},
}
less := func(a, b Album) bool { return a.Year < b.Year },
sorted := QuickSort(less, albums).([]Album)
Parallel map:
// Compute the prime factorization concurrently
// for every integer in [1000, 10000].
primeFactors := func(n int) []int { // compute prime factors }
factors := ParMap(primeFactors, Range(1000, 10001)).([]int)
Asynchronous channel without a fixed size buffer:
s, r := AsyncChan(new(chan int))
send, recv := s.(chan<- int), r.(<-chan int)
// Send as much as you want.
for i := 0; i < 100; i++ {
s <- i
}
close(s)
for i := range recv {
// do something with `i`
}
Shuffle any slice in place:
jumbleMe := []string{"The", "quick", "brown", "fox"}
Shuffle(jumbleMe)
Function memoization:
// Memoizing a recursive function like `fibonacci`.
// Write it like normal:
var fib func(n int64) int64
fib = func(n int64) int64 {
switch n {
case 0:
return 0
case 1:
return 1
}
return fib(n - 1) + fib(n - 2)
}
// And wrap it with `Memo`.
fib = Memo(fib).(func(int64) int64)
// Will keep your CPU busy for a long time
// without memoization.
fmt.Println(fib(80))
*/
package fun

35
vendor/github.com/BurntSushi/ty/fun/func.go generated vendored Normal file
View file

@ -0,0 +1,35 @@
package fun
import (
"reflect"
"github.com/BurntSushi/ty"
)
// Memo has a parametric type:
//
// func Memo(f func(A) B) func(A) B
//
// Memo memoizes any function of a single argument that returns a single value.
// The type `A` must be a Go type for which the comparison operators `==` and
// `!=` are fully defined (this rules out functions, maps and slices).
func Memo(f interface{}) interface{} {
chk := ty.Check(
new(func(func(ty.A) ty.B)),
f)
vf := chk.Args[0]
saved := make(map[interface{}]reflect.Value)
memo := func(in []reflect.Value) []reflect.Value {
val := in[0].Interface()
ret, ok := saved[val]
if ok {
return []reflect.Value{ret}
}
ret = call1(vf, in[0])
saved[val] = ret
return []reflect.Value{ret}
}
return reflect.MakeFunc(vf.Type(), memo).Interface()
}

303
vendor/github.com/BurntSushi/ty/fun/list.go generated vendored Normal file
View file

@ -0,0 +1,303 @@
package fun
import (
"reflect"
"runtime"
"sync"
"github.com/BurntSushi/ty"
)
// All has a parametric type:
//
// func All(p func(A) bool, xs []A) bool
//
// All returns `true` if and only if every element in `xs` satisfies `p`.
func All(f, xs interface{}) bool {
chk := ty.Check(
new(func(func(ty.A) bool, []ty.A) bool),
f, xs)
vf, vxs := chk.Args[0], chk.Args[1]
xsLen := vxs.Len()
for i := 0; i < xsLen; i++ {
if !call1(vf, vxs.Index(i)).Interface().(bool) {
return false
}
}
return true
}
// Exists has a parametric type:
//
// func Exists(p func(A) bool, xs []A) bool
//
// Exists returns `true` if and only if an element in `xs` satisfies `p`.
func Exists(f, xs interface{}) bool {
chk := ty.Check(
new(func(func(ty.A) bool, []ty.A) bool),
f, xs)
vf, vxs := chk.Args[0], chk.Args[1]
xsLen := vxs.Len()
for i := 0; i < xsLen; i++ {
if call1(vf, vxs.Index(i)).Interface().(bool) {
return true
}
}
return false
}
// In has a parametric type:
//
// func In(needle A, haystack []A) bool
//
// In returns `true` if and only if `v` can be found in `xs`. The equality test
// used is Go's standard `==` equality and NOT deep equality.
//
// Note that this requires that `A` be a type that can be meaningfully compared.
func In(needle, haystack interface{}) bool {
chk := ty.Check(
new(func(ty.A, []ty.A) bool),
needle, haystack)
vhaystack := chk.Args[1]
length := vhaystack.Len()
for i := 0; i < length; i++ {
if vhaystack.Index(i).Interface() == needle {
return true
}
}
return false
}
// Map has a parametric type:
//
// func Map(f func(A) B, xs []A) []B
//
// Map returns the list corresponding to the return value of applying
// `f` to each element in `xs`.
func Map(f, xs interface{}) interface{} {
chk := ty.Check(
new(func(func(ty.A) ty.B, []ty.A) []ty.B),
f, xs)
vf, vxs, tys := chk.Args[0], chk.Args[1], chk.Returns[0]
xsLen := vxs.Len()
vys := reflect.MakeSlice(tys, xsLen, xsLen)
for i := 0; i < xsLen; i++ {
vy := call1(vf, vxs.Index(i))
vys.Index(i).Set(vy)
}
return vys.Interface()
}
// Filter has a parametric type:
//
// func Filter(p func(A) bool, xs []A) []A
//
// Filter returns a new list only containing the elements of `xs` that satisfy
// the predicate `p`.
func Filter(p, xs interface{}) interface{} {
chk := ty.Check(
new(func(func(ty.A) bool, []ty.A) []ty.A),
p, xs)
vp, vxs, tys := chk.Args[0], chk.Args[1], chk.Returns[0]
xsLen := vxs.Len()
vys := reflect.MakeSlice(tys, 0, xsLen)
for i := 0; i < xsLen; i++ {
vx := vxs.Index(i)
if call1(vp, vx).Bool() {
vys = reflect.Append(vys, vx)
}
}
return vys.Interface()
}
// Foldl has a parametric type:
//
// func Foldl(f func(A, B) B, init B, xs []A) B
//
// Foldl reduces a list of A to a single element B using a left fold with
// an initial value `init`.
func Foldl(f, init, xs interface{}) interface{} {
chk := ty.Check(
new(func(func(ty.A, ty.B) ty.B, ty.B, []ty.A) ty.B),
f, init, xs)
vf, vinit, vxs, tb := chk.Args[0], chk.Args[1], chk.Args[2], chk.Returns[0]
xsLen := vxs.Len()
vb := zeroValue(tb)
vb.Set(vinit)
if xsLen == 0 {
return vb.Interface()
}
vb.Set(call1(vf, vxs.Index(0), vb))
for i := 1; i < xsLen; i++ {
vb.Set(call1(vf, vxs.Index(i), vb))
}
return vb.Interface()
}
// Foldr has a parametric type:
//
// func Foldr(f func(A, B) B, init B, xs []A) B
//
// Foldr reduces a list of A to a single element B using a right fold with
// an initial value `init`.
func Foldr(f, init, xs interface{}) interface{} {
chk := ty.Check(
new(func(func(ty.A, ty.B) ty.B, ty.B, []ty.A) ty.B),
f, init, xs)
vf, vinit, vxs, tb := chk.Args[0], chk.Args[1], chk.Args[2], chk.Returns[0]
xsLen := vxs.Len()
vb := zeroValue(tb)
vb.Set(vinit)
if xsLen == 0 {
return vb.Interface()
}
vb.Set(call1(vf, vxs.Index(xsLen-1), vb))
for i := xsLen - 2; i >= 0; i-- {
vb.Set(call1(vf, vxs.Index(i), vb))
}
return vb.Interface()
}
// Concat has a parametric type:
//
// func Concat(xs [][]A) []A
//
// Concat returns a new flattened list by appending all elements of `xs`.
func Concat(xs interface{}) interface{} {
chk := ty.Check(
new(func([][]ty.A) []ty.A),
xs)
vxs, tflat := chk.Args[0], chk.Returns[0]
xsLen := vxs.Len()
vflat := reflect.MakeSlice(tflat, 0, xsLen*3)
for i := 0; i < xsLen; i++ {
vflat = reflect.AppendSlice(vflat, vxs.Index(i))
}
return vflat.Interface()
}
// Reverse has a parametric type:
//
// func Reverse(xs []A) []A
//
// Reverse returns a new slice that is the reverse of `xs`.
func Reverse(xs interface{}) interface{} {
chk := ty.Check(
new(func([]ty.A) []ty.A),
xs)
vxs, tys := chk.Args[0], chk.Returns[0]
xsLen := vxs.Len()
vys := reflect.MakeSlice(tys, xsLen, xsLen)
for i := 0; i < xsLen; i++ {
vys.Index(i).Set(vxs.Index(xsLen - 1 - i))
}
return vys.Interface()
}
// Copy has a parametric type:
//
// func Copy(xs []A) []A
//
// Copy returns a copy of `xs` using Go's `copy` operation.
func Copy(xs interface{}) interface{} {
chk := ty.Check(
new(func([]ty.A) []ty.A),
xs)
vxs, tys := chk.Args[0], chk.Returns[0]
xsLen := vxs.Len()
vys := reflect.MakeSlice(tys, xsLen, xsLen)
reflect.Copy(vys, vxs)
return vys.Interface()
}
// ParMap has a parametric type:
//
// func ParMap(f func(A) B, xs []A) []B
//
// ParMap is just like Map, except it applies `f` to each element in `xs`
// concurrently using N worker goroutines (where N is the number of CPUs
// available reported by the Go runtime). If you want to control the number
// of goroutines spawned, use `ParMapN`.
//
// It is important that `f` not be a trivial operation, otherwise the overhead
// of executing it concurrently will result in worse performance than using
// a `Map`.
func ParMap(f, xs interface{}) interface{} {
n := runtime.NumCPU()
if n < 1 {
n = 1
}
return ParMapN(f, xs, n)
}
// ParMapN has a parametric type:
//
// func ParMapN(f func(A) B, xs []A, n int) []B
//
// ParMapN is just like Map, except it applies `f` to each element in `xs`
// concurrently using `n` worker goroutines.
//
// It is important that `f` not be a trivial operation, otherwise the overhead
// of executing it concurrently will result in worse performance than using
// a `Map`.
func ParMapN(f, xs interface{}, n int) interface{} {
chk := ty.Check(
new(func(func(ty.A) ty.B, []ty.A) []ty.B),
f, xs)
vf, vxs, tys := chk.Args[0], chk.Args[1], chk.Returns[0]
xsLen := vxs.Len()
ys := reflect.MakeSlice(tys, xsLen, xsLen)
if n < 1 {
n = 1
}
work := make(chan int, n)
wg := new(sync.WaitGroup)
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
for j := range work {
// Good golly miss molly. Is `reflect.Value.Index`
// safe to access/set from multiple goroutines?
// XXX: If not, we'll need an extra wave of allocation to
// use real slices of `reflect.Value`.
ys.Index(j).Set(call1(vf, vxs.Index(j)))
}
wg.Done()
}()
}
for i := 0; i < xsLen; i++ {
work <- i
}
close(work)
wg.Wait()
return ys.Interface()
}
// Range generates a list of integers corresponding to every integer in
// the half-open interval [x, y).
//
// Range will panic if `end < start`.
func Range(start, end int) []int {
if end < start {
panic("range must have end greater than or equal to start")
}
r := make([]int, end-start)
for i := start; i < end; i++ {
r[i-start] = i
}
return r
}

46
vendor/github.com/BurntSushi/ty/fun/map.go generated vendored Normal file
View file

@ -0,0 +1,46 @@
package fun
import (
"reflect"
"github.com/BurntSushi/ty"
)
// Keys has a parametric type:
//
// func Keys(m map[A]B) []A
//
// Keys returns a list of the keys of `m` in an unspecified order.
func Keys(m interface{}) interface{} {
chk := ty.Check(
new(func(map[ty.A]ty.B) []ty.A),
m)
vm, tkeys := chk.Args[0], chk.Returns[0]
vkeys := reflect.MakeSlice(tkeys, vm.Len(), vm.Len())
for i, vkey := range vm.MapKeys() {
vkeys.Index(i).Set(vkey)
}
return vkeys.Interface()
}
// Values has a parametric type:
//
// func Values(m map[A]B) []B
//
// Values returns a list of the values of `m` in an unspecified order.
func Values(m interface{}) interface{} {
chk := ty.Check(
new(func(map[ty.A]ty.B) []ty.B),
m)
vm, tvals := chk.Args[0], chk.Returns[0]
vvals := reflect.MakeSlice(tvals, vm.Len(), vm.Len())
for i, vkey := range vm.MapKeys() {
vvals.Index(i).Set(vm.MapIndex(vkey))
}
return vvals.Interface()
}
// func MapMerge(m1, m2 interface{}) interface{} {
// }

94
vendor/github.com/BurntSushi/ty/fun/rand.go generated vendored Normal file
View file

@ -0,0 +1,94 @@
package fun
import (
"math/rand"
"reflect"
"time"
"github.com/BurntSushi/ty"
)
var randNumGen *rand.Rand
func init() {
randNumGen = rand.New(rand.NewSource(time.Now().UnixNano()))
}
// ShuffleGen has a parametric type:
//
// func ShuffleGen(xs []A, rng *rand.Rand)
//
// ShuffleGen shuffles `xs` in place using the given random number
// generator `rng`.
func ShuffleGen(xs interface{}, rng *rand.Rand) {
chk := ty.Check(
new(func([]ty.A, *rand.Rand)),
xs, rng)
vxs := chk.Args[0]
// Implements the Fisher-Yates shuffle: http://goo.gl/Hb9vg
xsLen := vxs.Len()
swapper := swapperOf(vxs.Type().Elem())
for i := xsLen - 1; i >= 1; i-- {
j := rng.Intn(i + 1)
swapper.swap(vxs.Index(i), vxs.Index(j))
}
}
// Shuffle has a parametric type:
//
// func Shuffle(xs []A)
//
// Shuffle shuffles `xs` in place using a default random number
// generator seeded once at program initialization.
func Shuffle(xs interface{}) {
ShuffleGen(xs, randNumGen)
}
// Sample has a parametric type:
//
// func Sample(population []A, n int) []A
//
// Sample returns a random sample of size `n` from a list
// `population` using a default random number generator seeded once at
// program initialization.
// All elements in `population` have an equal chance of being selected.
// If `n` is greater than the size of `population`, then `n` is set to
// the size of the population.
func Sample(population interface{}, n int) interface{} {
return SampleGen(population, n, randNumGen)
}
// SampleGen has a parametric type:
//
// func SampleGen(population []A, n int, rng *rand.Rand) []A
//
// SampleGen returns a random sample of size `n` from a list
// `population` using a given random number generator `rng`.
// All elements in `population` have an equal chance of being selected.
// If `n` is greater than the size of `population`, then `n` is set to
// the size of the population.
func SampleGen(population interface{}, n int, rng *rand.Rand) interface{} {
chk := ty.Check(
new(func([]ty.A, int, *rand.Rand) []ty.A),
population, n, rng)
rpop, tsamp := chk.Args[0], chk.Returns[0]
popLen := rpop.Len()
if n == 0 {
return reflect.MakeSlice(tsamp, 0, 0).Interface()
}
if n > popLen {
n = popLen
}
// TODO(burntsushi): Implement an algorithm that doesn't depend on
// the size of the population.
rsamp := reflect.MakeSlice(tsamp, n, n)
choices := rng.Perm(popLen)
for i := 0; i < n; i++ {
rsamp.Index(i).Set(rpop.Index(choices[i]))
}
return rsamp.Interface()
}

99
vendor/github.com/BurntSushi/ty/fun/set.go generated vendored Normal file
View file

@ -0,0 +1,99 @@
package fun
import (
"reflect"
"github.com/BurntSushi/ty"
)
// Set has a parametric type:
//
// func Set(xs []A) map[A]bool
//
// Set creates a set from a list.
func Set(xs interface{}) interface{} {
chk := ty.Check(
new(func([]ty.A) map[ty.A]bool),
xs)
vxs, tset := chk.Args[0], chk.Returns[0]
vtrue := reflect.ValueOf(true)
vset := reflect.MakeMap(tset)
xsLen := vxs.Len()
for i := 0; i < xsLen; i++ {
vset.SetMapIndex(vxs.Index(i), vtrue)
}
return vset.Interface()
}
// Union has a parametric type:
//
// func Union(a map[A]bool, b map[A]bool) map[A]bool
//
// Union returns the union of two sets, where a set is represented as a
// `map[A]bool`. The sets `a` and `b` are not modified.
func Union(a, b interface{}) interface{} {
chk := ty.Check(
new(func(map[ty.A]bool, map[ty.A]bool) map[ty.A]bool),
a, b)
va, vb, tc := chk.Args[0], chk.Args[1], chk.Returns[0]
vtrue := reflect.ValueOf(true)
vc := reflect.MakeMap(tc)
for _, vkey := range va.MapKeys() {
vc.SetMapIndex(vkey, vtrue)
}
for _, vkey := range vb.MapKeys() {
vc.SetMapIndex(vkey, vtrue)
}
return vc.Interface()
}
// Intersection has a parametric type:
//
// func Intersection(a map[A]bool, b map[A]bool) map[A]bool
//
// Intersection returns the intersection of two sets, where a set is
// represented as a `map[A]bool`. The sets `a` and `b` are not modified.
func Intersection(a, b interface{}) interface{} {
chk := ty.Check(
new(func(map[ty.A]bool, map[ty.A]bool) map[ty.A]bool),
a, b)
va, vb, tc := chk.Args[0], chk.Args[1], chk.Returns[0]
vtrue := reflect.ValueOf(true)
vc := reflect.MakeMap(tc)
for _, vkey := range va.MapKeys() {
if vb.MapIndex(vkey).IsValid() {
vc.SetMapIndex(vkey, vtrue)
}
}
for _, vkey := range vb.MapKeys() {
if va.MapIndex(vkey).IsValid() {
vc.SetMapIndex(vkey, vtrue)
}
}
return vc.Interface()
}
// Difference has a parametric type:
//
// func Difference(a map[A]bool, b map[A]bool) map[A]bool
//
// Difference returns a set with all elements in `a` that are not in `b`.
// The sets `a` and `b` are not modified.
func Difference(a, b interface{}) interface{} {
chk := ty.Check(
new(func(map[ty.A]bool, map[ty.A]bool) map[ty.A]bool),
a, b)
va, vb, tc := chk.Args[0], chk.Args[1], chk.Returns[0]
vtrue := reflect.ValueOf(true)
vc := reflect.MakeMap(tc)
for _, vkey := range va.MapKeys() {
if !vb.MapIndex(vkey).IsValid() {
vc.SetMapIndex(vkey, vtrue)
}
}
return vc.Interface()
}

98
vendor/github.com/BurntSushi/ty/fun/sort.go generated vendored Normal file
View file

@ -0,0 +1,98 @@
package fun
import (
"reflect"
"sort"
"github.com/BurntSushi/ty"
)
// QuickSort has a parametric type:
//
// func QuickSort(less func(x1 A, x2 A) bool, []A) []A
//
// QuickSort applies the "quicksort" algorithm to return a new sorted list
// of `xs`, where `xs` is not modified.
//
// `less` should be a function that returns true if and only if `x1` is less
// than `x2`.
func QuickSort(less, xs interface{}) interface{} {
chk := ty.Check(
new(func(func(ty.A, ty.A) bool, []ty.A) []ty.A),
less, xs)
vless, vxs, tys := chk.Args[0], chk.Args[1], chk.Returns[0]
var qsort func(left, right int)
var partition func(left, right, pivot int) int
xsind := Range(0, vxs.Len())
qsort = func(left, right int) {
if left >= right {
return
}
pivot := (left + right) / 2
pivot = partition(left, right, pivot)
qsort(left, pivot-1)
qsort(pivot+1, right)
}
partition = func(left, right, pivot int) int {
vpivot := xsind[pivot]
xsind[pivot], xsind[right] = xsind[right], xsind[pivot]
ind := left
for i := left; i < right; i++ {
if call1(vless, vxs.Index(xsind[i]), vxs.Index(vpivot)).Bool() {
xsind[i], xsind[ind] = xsind[ind], xsind[i]
ind++
}
}
xsind[ind], xsind[right] = xsind[right], xsind[ind]
return ind
}
// Sort `xsind` in place.
qsort(0, len(xsind)-1)
vys := reflect.MakeSlice(tys, len(xsind), len(xsind))
for i, xsIndex := range xsind {
vys.Index(i).Set(vxs.Index(xsIndex))
}
return vys.Interface()
}
// Sort has a parametric type:
//
// func Sort(less func(x1 A, x2 A) bool, []A)
//
// Sort uses the standard library `sort` package to sort `xs` in place.
//
// `less` should be a function that returns true if and only if `x1` is less
// than `x2`.
func Sort(less, xs interface{}) {
chk := ty.Check(
new(func(func(ty.A, ty.A) bool, []ty.A)),
less, xs)
vless, vxs := chk.Args[0], chk.Args[1]
sort.Sort(&sortable{vless, vxs, swapperOf(vxs.Type().Elem())})
}
type sortable struct {
less reflect.Value
xs reflect.Value
swapper swapper
}
func (s *sortable) Less(i, j int) bool {
ith, jth := s.xs.Index(i), s.xs.Index(j)
return call1(s.less, ith, jth).Bool()
}
func (s *sortable) Swap(i, j int) {
s.swapper.swap(s.xs.Index(i), s.xs.Index(j))
}
func (s *sortable) Len() int {
return s.xs.Len()
}

37
vendor/github.com/BurntSushi/ty/fun/util.go generated vendored Normal file
View file

@ -0,0 +1,37 @@
package fun
import (
"reflect"
)
func zeroValue(typ reflect.Type) reflect.Value {
return reflect.New(typ).Elem()
}
type swapper reflect.Value
func swapperOf(typ reflect.Type) swapper {
return swapper(zeroValue(typ))
}
func (s swapper) swap(a, b reflect.Value) {
vs := reflect.Value(s)
vs.Set(a)
a.Set(b)
b.Set(vs)
}
func call(f reflect.Value, args ...reflect.Value) {
f.Call(args)
}
func call1(f reflect.Value, args ...reflect.Value) reflect.Value {
return f.Call(args)[0]
}
func call2(f reflect.Value, args ...reflect.Value) (
reflect.Value, reflect.Value) {
ret := f.Call(args)
return ret[0], ret[1]
}

338
vendor/github.com/BurntSushi/ty/type-check.go generated vendored Normal file
View file

@ -0,0 +1,338 @@
package ty
import (
"fmt"
"reflect"
"strings"
)
// TypeError corresponds to any error reported by the `Check` function.
// Since `Check` panics, if you want to run `Check` safely, it is
// appropriate to recover and use a type switch to discover a `TypeError`
// value.
type TypeError string
func (te TypeError) Error() string {
return string(te)
}
func pe(format string, v ...interface{}) TypeError {
return TypeError(fmt.Sprintf(format, v...))
}
func ppe(format string, v ...interface{}) {
panic(pe(format, v...))
}
// Typed corresponds to the information returned by `Check`.
type Typed struct {
// In correspondence with the `as` parameter to `Check`.
Args []reflect.Value
// In correspondence with the return types of `f` in `Check`.
Returns []reflect.Type
// The type environment generated via unification in `Check`.
// (Its usefulness in the public API is questionable.)
TypeEnv map[string]reflect.Type
}
// Check accepts a function `f`, which may have a parametric type, along with a
// number of arguments in correspondence with the arguments to `f`,
// and returns inferred Go type information. This type information includes
// a list of `reflect.Value` in correspondence with `as`, a list of
// `reflect.Type` in correspondence with the return types of `f` and a type
// environment mapping type variables to `reflect.Type`.
//
// The power of `Check` comes from the following invariant: if `Check` returns,
// then the types of the arguments corresponding to `as` are consistent
// with the parametric type of `f`, *and* the parametric return types of `f`
// were made into valid Go types that are not parametric. Otherwise, there is
// a bug in `Check`.
//
// More concretely, consider a simple parametric function `Map`, which
// transforms a list of elements by applying a function to each element in
// order to generate a new list. Such a function constructed only for integers
// might have a type like
//
// func Map(func(int) int, []int) []int
//
// But the parametric type of `Map` could be given with
//
// func Map(func(A) B, []A) []B
//
// which in English reads, "Given a function from any type `A` to any type `B`
// and a slice of `A`, `Map` returns a slice of `B`."
//
// To write a parametric function like `Map`, one can pass a pointer
// to a nil function of the desired parametric type to get the reflection
// information:
//
// func Map(f, xs interface{}) interface{} {
// // Given the parametric type and the arguments, Check will
// // return all the reflection information you need to write `Map`.
// uni := ty.Check(
// new(func(func(ty.A) ty.B, []ty.A) []ty.B),
// f, xs)
//
// // `vf` and `vxs` are `reflect.Value`s of `f` and `xs`.
// vf, vxs := uni.Args[0], uni.Args[1]
//
// // `tys` is a `reflect.Type` of `[]ty.B` where `ty.B` is replaced
// // with the return type of the given function `f`.
// tys := uni.Returns[0]
//
// // Given the promise of `Check`, we now know that `vf` has
// // type `func(ty.A) ty.B` and `vxs` has type `[]ty.A`.
// xsLen := vxs.Len()
//
// // Constructs a new slice which will have type `[]ty.B`.
// vys := reflect.MakeSlice(tys, xsLen, xsLen)
//
// // Actually perform the `Map` operation, but in the world of
// // reflection.
// for i := 0; i < xsLen; i++ {
// vy := vf.Call([]reflect.Value{vxs.Index(i)})[0]
// vys.Index(i).Set(vy)
// }
//
// // The `reflect.Value.Interface` method is how we exit the world of
// // reflection. The onus is now on the caller to type assert it to
// // the appropriate type.
// return vys.Interface()
// }
//
// Working in the reflection world is certainly more inconvenient than writing
// regular Go code, but the information and invariants held by `Check` provide
// a more convenient experience than how one normally works with reflection.
// (Notice that there is no error-prone type switching or boiler plate to
// construct new types, since `Check` guarantees the types are consistent
// with the inputs for us.)
//
// And while writing such functions is still not so convenient,
// invoking them is simple:
//
// square := func(x int) int { return x * x }
// squared := Map(square, []int{1, 2, 3, 4, 5}).([]int)
//
// Restrictions
//
// There are a few restrictions imposed on the parametric return types of
// `f`: type variables may only be found in types that can be composed by the
// `reflect` package. This *only* includes channels, maps, pointers and slices.
// If a type variable is found in an array, function or struct, `Check` will
// panic.
//
// Also, type variables inside of structs are ignored in the types of the
// arguments `as`. This restriction may be lifted in the future.
//
// To be clear: type variables *may* appear in arrays or functions in the types
// of the arguments `as`.
func Check(f interface{}, as ...interface{}) *Typed {
rf := reflect.ValueOf(f)
tf := rf.Type()
if tf.Kind() == reflect.Ptr {
rf = reflect.Indirect(rf)
tf = rf.Type()
}
if tf.Kind() != reflect.Func {
ppe("The type of `f` must be a function, but it is a '%s'.", tf.Kind())
}
if tf.NumIn() != len(as) {
ppe("`f` expects %d arguments, but only %d were given.",
tf.NumIn(), len(as))
}
// Populate the argument value list.
args := make([]reflect.Value, len(as))
for i := 0; i < len(as); i++ {
args[i] = reflect.ValueOf(as[i])
}
// Populate our type variable environment through unification.
tyenv := make(tyenv)
for i := 0; i < len(args); i++ {
tp := typePair{tyenv, tf.In(i), args[i].Type()}
// Mutates the type variable environment.
if err := tp.unify(tp.param, tp.input); err != nil {
argTypes := make([]string, len(args))
for i := range args {
argTypes[i] = args[i].Type().String()
}
ppe("\nError type checking\n\t%s\nwith argument types\n\t(%s)\n%s",
tf, strings.Join(argTypes, ", "), err)
}
}
// Now substitute those types into the return types of `f`.
retTypes := make([]reflect.Type, tf.NumOut())
for i := 0; i < tf.NumOut(); i++ {
retTypes[i] = (&returnType{tyenv, tf.Out(i)}).tysubst(tf.Out(i))
}
return &Typed{args, retTypes, map[string]reflect.Type(tyenv)}
}
// tyenv maps type variable names to their inferred Go type.
type tyenv map[string]reflect.Type
// typePair represents a pair of types to be unified. They act as a way to
// report sensible error messages from within the unification algorithm.
//
// It also includes a type environment, which is mutated during unification.
type typePair struct {
tyenv tyenv
param reflect.Type
input reflect.Type
}
func (tp typePair) error(format string, v ...interface{}) error {
return pe("Type error when unifying type '%s' and '%s': %s",
tp.param, tp.input, fmt.Sprintf(format, v...))
}
// unify attempts to satisfy a pair of types, where the `param` type is the
// expected type of a function argument and the `input` type is the known
// type of a function argument. The `param` type may be parametric (that is,
// it may contain a type that is convertible to TypeVariable) but the
// `input` type may *not* be parametric.
//
// Any failure to unify the two types results in a panic.
//
// The end result of unification is a type environment: a set of substitutions
// from type variable to a Go type.
func (tp typePair) unify(param, input reflect.Type) error {
if tyname := tyvarName(input); len(tyname) > 0 {
return tp.error("Type variables are not allowed in the types of " +
"arguments.")
}
if tyname := tyvarName(param); len(tyname) > 0 {
if cur, ok := tp.tyenv[tyname]; ok && cur != input {
return tp.error("Type variable %s expected type '%s' but got '%s'.",
tyname, cur, input)
} else if !ok {
tp.tyenv[tyname] = input
}
return nil
}
if param.Kind() != input.Kind() {
return tp.error("Cannot unify different kinds of types '%s' and '%s'.",
param, input)
}
switch param.Kind() {
case reflect.Array:
return tp.unify(param.Elem(), input.Elem())
case reflect.Chan:
if param.ChanDir() != input.ChanDir() {
return tp.error("Cannot unify '%s' with '%s' "+
"(channel directions are different: '%s' != '%s').",
param, input, param.ChanDir(), input.ChanDir())
}
return tp.unify(param.Elem(), input.Elem())
case reflect.Func:
if param.NumIn() != input.NumIn() || param.NumOut() != input.NumOut() {
return tp.error("Cannot unify '%s' with '%s'.", param, input)
}
for i := 0; i < param.NumIn(); i++ {
if err := tp.unify(param.In(i), input.In(i)); err != nil {
return err
}
}
for i := 0; i < param.NumOut(); i++ {
if err := tp.unify(param.Out(i), input.Out(i)); err != nil {
return err
}
}
case reflect.Map:
if err := tp.unify(param.Key(), input.Key()); err != nil {
return err
}
return tp.unify(param.Elem(), input.Elem())
case reflect.Ptr:
return tp.unify(param.Elem(), input.Elem())
case reflect.Slice:
return tp.unify(param.Elem(), input.Elem())
}
// The only other container types are Interface and Struct.
// I am unsure about what to do with interfaces. Mind is fuzzy.
// Structs? I don't think it really makes much sense to use type
// variables inside of them.
return nil
}
// returnType corresponds to the type of a single return value of a function,
// in which the type may be parametric. It also contains a type environment
// constructed from unification.
type returnType struct {
tyenv tyenv
typ reflect.Type
}
func (rt returnType) panic(format string, v ...interface{}) {
ppe("Error substituting in return type '%s': %s",
rt.typ, fmt.Sprintf(format, v...))
}
// tysubst attempts to substitute all type variables within a single return
// type with their corresponding Go type from the type environment.
//
// tysubst will panic if a type variable is unbound, or if it encounters a
// type that cannot be dynamically created. Such types include arrays,
// functions and structs. (A limitation of the `reflect` package.)
func (rt returnType) tysubst(typ reflect.Type) reflect.Type {
if tyname := tyvarName(typ); len(tyname) > 0 {
if thetype, ok := rt.tyenv[tyname]; !ok {
rt.panic("Unbound type variable %s.", tyname)
} else {
return thetype
}
}
switch typ.Kind() {
case reflect.Array:
rt.panic("Cannot dynamically create Array types.")
case reflect.Chan:
return reflect.ChanOf(typ.ChanDir(), rt.tysubst(typ.Elem()))
case reflect.Func:
rt.panic("Cannot dynamically create Function types.")
case reflect.Interface:
// rt.panic("TODO")
// Not sure if this is right.
return typ
case reflect.Map:
return reflect.MapOf(rt.tysubst(typ.Key()), rt.tysubst(typ.Elem()))
case reflect.Ptr:
return reflect.PtrTo(rt.tysubst(typ.Elem()))
case reflect.Slice:
return reflect.SliceOf(rt.tysubst(typ.Elem()))
case reflect.Struct:
rt.panic("Cannot dynamically create Struct types.")
case reflect.UnsafePointer:
rt.panic("Cannot dynamically create unsafe.Pointer types.")
}
// We've covered all the composite types, so we're only left with
// base types.
return typ
}
func tyvarName(t reflect.Type) string {
if !t.ConvertibleTo(tyvarUnderlyingType) {
return ""
}
return t.Name()
}
// AssertType panics with a `TypeError` if `v` does not have type `t`.
// Otherwise, it returns the `reflect.Value` of `v`.
func AssertType(v interface{}, t reflect.Type) reflect.Value {
rv := reflect.ValueOf(v)
tv := rv.Type()
if tv != t {
ppe("Value '%v' has type '%s' but expected '%s'.", v, tv, t)
}
return rv
}

28
vendor/github.com/BurntSushi/ty/tyvars.go generated vendored Normal file
View file

@ -0,0 +1,28 @@
package ty
import (
"reflect"
)
// TypeVariable is the underlying type of every type variable used in
// parametric types. It should not be used directly. Instead, use
//
// type myOwnTypeVariable TypeVariable
//
// to create your own type variable. For your convenience, this package
// defines some type variables for you. (e.g., `A`, `B`, `C`, ...)
type TypeVariable struct {
noImitation struct{}
}
// tyvarUnderlyingType is used to discover types that are type variables.
// Namely, any type variable must be convertible to `TypeVariable`.
var tyvarUnderlyingType = reflect.TypeOf(TypeVariable{})
type A TypeVariable
type B TypeVariable
type C TypeVariable
type D TypeVariable
type E TypeVariable
type F TypeVariable
type G TypeVariable