// Generated by tmpl
// https://github.com/benbjohnson/tmpl
//
// DO NOT EDIT!
// Source: iterator.gen.go.tmpl

package arrowutil

import "github.com/apache/arrow/go/arrow/array"

type Int64Iterator struct {
	Values []*array.Int64
	i      int
	init   bool
}

func IterateInt64s(arrs []array.Interface) Int64Iterator {
	if len(arrs) == 0 {
		return Int64Iterator{}
	}
	values := make([]*array.Int64, 0, len(arrs))
	for _, arr := range arrs {
		values = append(values, arr.(*array.Int64))
	}
	return Int64Iterator{Values: values}
}

// Value returns the current value in the iterator.
func (i *Int64Iterator) Value() int64 {
	vs := i.Values[0]
	return vs.Value(i.i)
}

// IsValid returns if the current value is valid.
func (i *Int64Iterator) IsValid() bool {
	vs := i.Values[0]
	return vs.IsValid(i.i)
}

// IsNull returns if the current value is null.
func (i *Int64Iterator) IsNull() bool {
	vs := i.Values[0]
	return vs.IsNull(i.i)
}

// Next will move to the next value. It will return false
// if there are no more values to be read. This will
// initialize the iterator if this is the first time it
// is called and return true if there is at least one element.
func (i *Int64Iterator) Next() bool {
	if !i.init {
		i.init = true
		return i.peek()
	}
	i.i++
	return i.peek()
}

// IsEmpty returns true if the iterator has no values to read.
func (i *Int64Iterator) IsEmpty() bool {
	return i.peek()
}

// peek will return whether another value is available.
// It will iterate through the iterators until it finds a valid one.
func (i *Int64Iterator) peek() bool {
	for len(i.Values) > 0 {
		if i.i < i.Values[0].Len() {
			return true
		}
		i.i = 0
		i.Values = i.Values[1:]
	}
	return false
}

type Uint64Iterator struct {
	Values []*array.Uint64
	i      int
	init   bool
}

func IterateUint64s(arrs []array.Interface) Uint64Iterator {
	if len(arrs) == 0 {
		return Uint64Iterator{}
	}
	values := make([]*array.Uint64, 0, len(arrs))
	for _, arr := range arrs {
		values = append(values, arr.(*array.Uint64))
	}
	return Uint64Iterator{Values: values}
}

// Value returns the current value in the iterator.
func (i *Uint64Iterator) Value() uint64 {
	vs := i.Values[0]
	return vs.Value(i.i)
}

// IsValid returns if the current value is valid.
func (i *Uint64Iterator) IsValid() bool {
	vs := i.Values[0]
	return vs.IsValid(i.i)
}

// IsNull returns if the current value is null.
func (i *Uint64Iterator) IsNull() bool {
	vs := i.Values[0]
	return vs.IsNull(i.i)
}

// Next will move to the next value. It will return false
// if there are no more values to be read. This will
// initialize the iterator if this is the first time it
// is called and return true if there is at least one element.
func (i *Uint64Iterator) Next() bool {
	if !i.init {
		i.init = true
		return i.peek()
	}
	i.i++
	return i.peek()
}

// IsEmpty returns true if the iterator has no values to read.
func (i *Uint64Iterator) IsEmpty() bool {
	return i.peek()
}

// peek will return whether another value is available.
// It will iterate through the iterators until it finds a valid one.
func (i *Uint64Iterator) peek() bool {
	for len(i.Values) > 0 {
		if i.i < i.Values[0].Len() {
			return true
		}
		i.i = 0
		i.Values = i.Values[1:]
	}
	return false
}

type Float64Iterator struct {
	Values []*array.Float64
	i      int
	init   bool
}

func IterateFloat64s(arrs []array.Interface) Float64Iterator {
	if len(arrs) == 0 {
		return Float64Iterator{}
	}
	values := make([]*array.Float64, 0, len(arrs))
	for _, arr := range arrs {
		values = append(values, arr.(*array.Float64))
	}
	return Float64Iterator{Values: values}
}

// Value returns the current value in the iterator.
func (i *Float64Iterator) Value() float64 {
	vs := i.Values[0]
	return vs.Value(i.i)
}

// IsValid returns if the current value is valid.
func (i *Float64Iterator) IsValid() bool {
	vs := i.Values[0]
	return vs.IsValid(i.i)
}

// IsNull returns if the current value is null.
func (i *Float64Iterator) IsNull() bool {
	vs := i.Values[0]
	return vs.IsNull(i.i)
}

// Next will move to the next value. It will return false
// if there are no more values to be read. This will
// initialize the iterator if this is the first time it
// is called and return true if there is at least one element.
func (i *Float64Iterator) Next() bool {
	if !i.init {
		i.init = true
		return i.peek()
	}
	i.i++
	return i.peek()
}

// IsEmpty returns true if the iterator has no values to read.
func (i *Float64Iterator) IsEmpty() bool {
	return i.peek()
}

// peek will return whether another value is available.
// It will iterate through the iterators until it finds a valid one.
func (i *Float64Iterator) peek() bool {
	for len(i.Values) > 0 {
		if i.i < i.Values[0].Len() {
			return true
		}
		i.i = 0
		i.Values = i.Values[1:]
	}
	return false
}

type BooleanIterator struct {
	Values []*array.Boolean
	i      int
	init   bool
}

func IterateBooleans(arrs []array.Interface) BooleanIterator {
	if len(arrs) == 0 {
		return BooleanIterator{}
	}
	values := make([]*array.Boolean, 0, len(arrs))
	for _, arr := range arrs {
		values = append(values, arr.(*array.Boolean))
	}
	return BooleanIterator{Values: values}
}

// Value returns the current value in the iterator.
func (i *BooleanIterator) Value() bool {
	vs := i.Values[0]
	return vs.Value(i.i)
}

// IsValid returns if the current value is valid.
func (i *BooleanIterator) IsValid() bool {
	vs := i.Values[0]
	return vs.IsValid(i.i)
}

// IsNull returns if the current value is null.
func (i *BooleanIterator) IsNull() bool {
	vs := i.Values[0]
	return vs.IsNull(i.i)
}

// Next will move to the next value. It will return false
// if there are no more values to be read. This will
// initialize the iterator if this is the first time it
// is called and return true if there is at least one element.
func (i *BooleanIterator) Next() bool {
	if !i.init {
		i.init = true
		return i.peek()
	}
	i.i++
	return i.peek()
}

// IsEmpty returns true if the iterator has no values to read.
func (i *BooleanIterator) IsEmpty() bool {
	return i.peek()
}

// peek will return whether another value is available.
// It will iterate through the iterators until it finds a valid one.
func (i *BooleanIterator) peek() bool {
	for len(i.Values) > 0 {
		if i.i < i.Values[0].Len() {
			return true
		}
		i.i = 0
		i.Values = i.Values[1:]
	}
	return false
}

type StringIterator struct {
	Values []*array.Binary
	i      int
	init   bool
}

func IterateStrings(arrs []array.Interface) StringIterator {
	if len(arrs) == 0 {
		return StringIterator{}
	}
	values := make([]*array.Binary, 0, len(arrs))
	for _, arr := range arrs {
		values = append(values, arr.(*array.Binary))
	}
	return StringIterator{Values: values}
}

// ValueString returns the current value in the iterator.
func (i *StringIterator) ValueString() string {
	vs := i.Values[0]
	return vs.ValueString(i.i)
}

// IsValid returns if the current value is valid.
func (i *StringIterator) IsValid() bool {
	vs := i.Values[0]
	return vs.IsValid(i.i)
}

// IsNull returns if the current value is null.
func (i *StringIterator) IsNull() bool {
	vs := i.Values[0]
	return vs.IsNull(i.i)
}

// Next will move to the next value. It will return false
// if there are no more values to be read. This will
// initialize the iterator if this is the first time it
// is called and return true if there is at least one element.
func (i *StringIterator) Next() bool {
	if !i.init {
		i.init = true
		return i.peek()
	}
	i.i++
	return i.peek()
}

// IsEmpty returns true if the iterator has no values to read.
func (i *StringIterator) IsEmpty() bool {
	return i.peek()
}

// peek will return whether another value is available.
// It will iterate through the iterators until it finds a valid one.
func (i *StringIterator) peek() bool {
	for len(i.Values) > 0 {
		if i.i < i.Values[0].Len() {
			return true
		}
		i.i = 0
		i.Values = i.Values[1:]
	}
	return false
}
