init
This commit is contained in:
11
vendor/github.com/anacrolix/missinggo/iter/chain.go
generated
vendored
Normal file
11
vendor/github.com/anacrolix/missinggo/iter/chain.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package iter
|
||||
|
||||
func Chain(fs ...Func) Func {
|
||||
return func(cb Callback) {
|
||||
for _, f := range fs {
|
||||
if !All(cb, f) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
vendor/github.com/anacrolix/missinggo/iter/func.go
generated
vendored
Normal file
22
vendor/github.com/anacrolix/missinggo/iter/func.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package iter
|
||||
|
||||
// Callback receives a value and returns true if another value should be
|
||||
// received or false to stop iteration.
|
||||
type Callback func(value interface{}) (more bool)
|
||||
|
||||
// Func iterates by calling Callback for each of its values.
|
||||
type Func func(Callback)
|
||||
|
||||
func All(cb Callback, fs ...Func) bool {
|
||||
for _, f := range fs {
|
||||
all := true
|
||||
f(func(v interface{}) bool {
|
||||
all = all && cb(v)
|
||||
return all
|
||||
})
|
||||
if !all {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
105
vendor/github.com/anacrolix/missinggo/iter/groupby.go
generated
vendored
Normal file
105
vendor/github.com/anacrolix/missinggo/iter/groupby.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
package iter
|
||||
|
||||
type groupBy struct {
|
||||
curKey interface{}
|
||||
curKeyOk bool
|
||||
curValue interface{}
|
||||
keyFunc func(interface{}) interface{}
|
||||
input Iterator
|
||||
groupKey interface{}
|
||||
groupKeyOk bool
|
||||
}
|
||||
|
||||
type Group interface {
|
||||
Iterator
|
||||
Key() interface{}
|
||||
}
|
||||
|
||||
type group struct {
|
||||
gb *groupBy
|
||||
key interface{}
|
||||
first bool
|
||||
stopped bool
|
||||
}
|
||||
|
||||
func (me *group) Stop() {
|
||||
me.stopped = true
|
||||
}
|
||||
|
||||
func (me *group) Next() (ok bool) {
|
||||
if me.stopped {
|
||||
return false
|
||||
}
|
||||
if me.first {
|
||||
me.first = false
|
||||
return true
|
||||
}
|
||||
me.gb.advance()
|
||||
if !me.gb.curKeyOk || me.gb.curKey != me.key {
|
||||
me.Stop()
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
func (me group) Value() (ret interface{}) {
|
||||
if me.stopped {
|
||||
panic("iterator stopped")
|
||||
}
|
||||
ret = me.gb.curValue
|
||||
return
|
||||
}
|
||||
|
||||
func (me group) Key() interface{} {
|
||||
return me.key
|
||||
}
|
||||
|
||||
func (me *groupBy) advance() {
|
||||
me.curKeyOk = me.input.Next()
|
||||
if me.curKeyOk {
|
||||
me.curValue = me.input.Value()
|
||||
me.curKey = me.keyFunc(me.curValue)
|
||||
}
|
||||
}
|
||||
|
||||
func (me *groupBy) Next() (ok bool) {
|
||||
for me.curKey == me.groupKey {
|
||||
ok = me.input.Next()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
me.curValue = me.input.Value()
|
||||
me.curKey = me.keyFunc(me.curValue)
|
||||
me.curKeyOk = true
|
||||
}
|
||||
me.groupKey = me.curKey
|
||||
me.groupKeyOk = true
|
||||
return true
|
||||
}
|
||||
|
||||
func (me *groupBy) Value() (ret interface{}) {
|
||||
return &group{me, me.groupKey, true, false}
|
||||
}
|
||||
|
||||
func (me *groupBy) Stop() {
|
||||
}
|
||||
|
||||
// Allows use of nil as a return from the key func.
|
||||
var uniqueKey = new(int)
|
||||
|
||||
// Group by returns an iterator of iterators over the values of the input
|
||||
// iterator that consecutively return the same value when input to the key
|
||||
// function. Note that repeated calls to each value of the GroupBy Iterator
|
||||
// does not return a new iterator over the values for that key.
|
||||
func GroupBy(input Iterator, keyFunc func(interface{}) interface{}) Iterator {
|
||||
if keyFunc == nil {
|
||||
keyFunc = func(a interface{}) interface{} { return a }
|
||||
}
|
||||
return &groupBy{
|
||||
input: input,
|
||||
keyFunc: keyFunc,
|
||||
groupKey: uniqueKey,
|
||||
curKey: uniqueKey,
|
||||
}
|
||||
}
|
||||
16
vendor/github.com/anacrolix/missinggo/iter/head.go
generated
vendored
Normal file
16
vendor/github.com/anacrolix/missinggo/iter/head.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
package iter
|
||||
|
||||
func Head(n int, f Func) Func {
|
||||
return func(cb Callback) {
|
||||
if n <= 0 {
|
||||
return
|
||||
}
|
||||
f(func(v interface{}) bool {
|
||||
n--
|
||||
if !cb(v) {
|
||||
return false
|
||||
}
|
||||
return n > 0
|
||||
})
|
||||
}
|
||||
}
|
||||
69
vendor/github.com/anacrolix/missinggo/iter/iterable.go
generated
vendored
Normal file
69
vendor/github.com/anacrolix/missinggo/iter/iterable.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package iter
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/anacrolix/missinggo"
|
||||
)
|
||||
|
||||
type Iterable interface {
|
||||
Iter(Callback)
|
||||
}
|
||||
|
||||
type iterator struct {
|
||||
it Iterable
|
||||
ch chan interface{}
|
||||
value interface{}
|
||||
ok bool
|
||||
mu sync.Mutex
|
||||
stopped missinggo.Event
|
||||
}
|
||||
|
||||
func NewIterator(it Iterable) (ret *iterator) {
|
||||
ret = &iterator{
|
||||
it: it,
|
||||
ch: make(chan interface{}),
|
||||
}
|
||||
go func() {
|
||||
// Have to do this in a goroutine, because the interface is synchronous.
|
||||
it.Iter(func(value interface{}) bool {
|
||||
select {
|
||||
case ret.ch <- value:
|
||||
return true
|
||||
case <-ret.stopped.LockedChan(&ret.mu):
|
||||
return false
|
||||
}
|
||||
})
|
||||
close(ret.ch)
|
||||
ret.mu.Lock()
|
||||
ret.stopped.Set()
|
||||
ret.mu.Unlock()
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
||||
func (me *iterator) Value() interface{} {
|
||||
if !me.ok {
|
||||
panic("no value")
|
||||
}
|
||||
return me.value
|
||||
}
|
||||
|
||||
func (me *iterator) Next() bool {
|
||||
me.value, me.ok = <-me.ch
|
||||
return me.ok
|
||||
}
|
||||
|
||||
func (me *iterator) Stop() {
|
||||
me.mu.Lock()
|
||||
me.stopped.Set()
|
||||
me.mu.Unlock()
|
||||
}
|
||||
|
||||
func IterableAsSlice(it Iterable) (ret []interface{}) {
|
||||
it.Iter(func(value interface{}) bool {
|
||||
ret = append(ret, value)
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
69
vendor/github.com/anacrolix/missinggo/iter/iterator.go
generated
vendored
Normal file
69
vendor/github.com/anacrolix/missinggo/iter/iterator.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package iter
|
||||
|
||||
import "github.com/anacrolix/missinggo/slices"
|
||||
|
||||
type Iterator interface {
|
||||
// Advances to the next value. Returns false if there are no more values.
|
||||
// Must be called before the first value.
|
||||
Next() bool
|
||||
// Returns the current value. Should panic when the iterator is in an
|
||||
// invalid state.
|
||||
Value() interface{}
|
||||
// Ceases iteration prematurely. This should occur implicitly if Next
|
||||
// returns false.
|
||||
Stop()
|
||||
}
|
||||
|
||||
func ToFunc(it Iterator) Func {
|
||||
return func(cb Callback) {
|
||||
defer it.Stop()
|
||||
for it.Next() {
|
||||
if !cb(it.Value()) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type sliceIterator struct {
|
||||
slice []interface{}
|
||||
value interface{}
|
||||
ok bool
|
||||
}
|
||||
|
||||
func (me *sliceIterator) Next() bool {
|
||||
if len(me.slice) == 0 {
|
||||
return false
|
||||
}
|
||||
me.value = me.slice[0]
|
||||
me.slice = me.slice[1:]
|
||||
me.ok = true
|
||||
return true
|
||||
}
|
||||
|
||||
func (me *sliceIterator) Value() interface{} {
|
||||
if !me.ok {
|
||||
panic("no value; call Next")
|
||||
}
|
||||
return me.value
|
||||
}
|
||||
|
||||
func (me *sliceIterator) Stop() {}
|
||||
|
||||
func Slice(a []interface{}) Iterator {
|
||||
return &sliceIterator{
|
||||
slice: a,
|
||||
}
|
||||
}
|
||||
|
||||
func StringIterator(a string) Iterator {
|
||||
return Slice(slices.ToEmptyInterface(a))
|
||||
}
|
||||
|
||||
func ToSlice(f Func) (ret []interface{}) {
|
||||
f(func(v interface{}) bool {
|
||||
ret = append(ret, v)
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
42
vendor/github.com/anacrolix/missinggo/iter/iterutils.go
generated
vendored
Normal file
42
vendor/github.com/anacrolix/missinggo/iter/iterutils.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package iter
|
||||
|
||||
import "math/rand"
|
||||
|
||||
type seq struct {
|
||||
i []int
|
||||
}
|
||||
|
||||
// Creates sequence of values from [0, n)
|
||||
func newSeq(n int) seq {
|
||||
return seq{make([]int, n, n)}
|
||||
}
|
||||
|
||||
func (me seq) Index(i int) (ret int) {
|
||||
ret = me.i[i]
|
||||
if ret == 0 {
|
||||
ret = i
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (me seq) Len() int {
|
||||
return len(me.i)
|
||||
}
|
||||
|
||||
// Remove the nth value from the sequence.
|
||||
func (me *seq) DeleteIndex(index int) {
|
||||
me.i[index] = me.Index(me.Len() - 1)
|
||||
me.i = me.i[:me.Len()-1]
|
||||
}
|
||||
|
||||
func ForPerm(n int, callback func(i int) (more bool)) bool {
|
||||
s := newSeq(n)
|
||||
for s.Len() > 0 {
|
||||
r := rand.Intn(s.Len())
|
||||
if !callback(s.Index(r)) {
|
||||
return false
|
||||
}
|
||||
s.DeleteIndex(r)
|
||||
}
|
||||
return true
|
||||
}
|
||||
7
vendor/github.com/anacrolix/missinggo/iter/n.go
generated
vendored
Normal file
7
vendor/github.com/anacrolix/missinggo/iter/n.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package iter
|
||||
|
||||
import "github.com/bradfitz/iter"
|
||||
|
||||
func N(n int) []struct{} {
|
||||
return iter.N(n)
|
||||
}
|
||||
Reference in New Issue
Block a user