You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.8 KiB
Go

3 years ago
package iter
import "constraints"
// Able is anything that is iter.Able
type Able[T any] interface {
Iter() Ator[T]
}
// Ator is an iter.Ator
type Ator[T any] interface {
// Next assigns the value pointed at by *T to the next value in the
// iteration. Next should return true if a value was set. An Ator that
// returns false should continue to return false; once iteration is
// complete it should be complete forever.
Next(*T) bool
3 years ago
// An iterator must also be iterable. That is, a valid iterator must be
// able to create a new iterator beginning at the same position of that
// iterator, such that calling Iter() on an Iterator returns a new
// Iterator, and that both can be iterated without affecting one another.
Able[T]
3 years ago
}
3 years ago
// Start starts the iteration for an Iterable. This is a convenience function
// to facilitate iterating in a for loop. E.g., given an Iterable value l, such
// as a list, the following would iterate over the entire iterable:
//
// for v, it := iter.Start(l); it.Next(&v); {
// // utilize v here
// }
//
// Without such a construct, a developer would have to do something similar instead:
//
// for v, it := 0, l.Iter(); it.Next(&v); {
//
// }
//
// Doing that would require that the developer type out the zero-value for that
// type, when that value could just as easily be inferred.
func Start[T any](a Able[T]) (T, Ator[T]) {
3 years ago
var v T
return v, a.Iter()
}
3 years ago
func Min[T constraints.Ordered](src Able[T]) T {
it := src.Iter()
3 years ago
var v T
if !it.Next(&v) {
var zero T
return zero
}
min := v
for it.Next(&v) {
if v < min {
min = v
}
}
return min
}
3 years ago
func Max[T constraints.Ordered](src Able[T]) T {
it := src.Iter()
3 years ago
var v T
if !it.Next(&v) {
var zero T
return zero
}
max := v
for it.Next(&v) {
if v > max {
max = v
}
}
return max
}