/* Package "iterator" */ package iterator import "fmt" // An iterator over slices. type Iterator[T any] struct { items []T index int } // Create a new iterator, over a set of items. func Of[T any](items []T) *Iterator[T] { return &Iterator[T]{items: items, index: 0} } // Returns the current position of the iterator. func (i Iterator[T]) Index() int { return i.index } func (i Iterator[T]) Copy() *Iterator[T] { return &Iterator[T]{items: i.items, index: i.index} } func (i *Iterator[T]) Sync(o *Iterator[T]) { i.index = o.index } // Create a new iterator, over a set of items. func (i Iterator[T]) Get() (T, error) { var null T if i.Done() { return null, fmt.Errorf("iterator is exhausted") } return i.items[i.index], nil } func (i Iterator[T]) MustGet() T { var null T if i.Done() { return null } return i.items[i.index] } func (i *Iterator[T]) Forward() { if !i.Done() { i.index++ } } // Create a new iterator, over a set of items. func (i *Iterator[T]) Next() (T, error) { item, err := i.Get() if err == nil { i.index++ } return item, err } // Create a new iterator, over a set of items. func (i *Iterator[T]) Back() { i.index = max(i.index-1, 0) } // Returns the current position of the iterator. func (i Iterator[T]) Done() bool { return i.index == len(i.items) } func Do[T any, U any](i *Iterator[T], fn func(i *Iterator[T]) (U, error)) (U, error) { i2 := i.Copy() out, err := fn(i2) if err == nil { i.Sync(i2) } return out, err }