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.

41 lines
1.5 KiB
Kotlin

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package moe.kageru.sekwences
/**
* Sequence that holds a [CoalescingIterator].
*/
internal class CoalescingSequence<T>(private val source: Sequence<T>, private inline val merger: (T, T) -> T?) : Sequence<T> {
override fun iterator(): Iterator<T> {
return CoalescingIterator(source.iterator(), merger)
}
/**
* Iterator that will attempt to merge adjacent elements as described in the KDoc for [coalesce].
*/
internal class CoalescingIterator<T>(private val source: Iterator<T>, private inline val merger: (T, T) -> T?) : Iterator<T> {
private var previous: T = if (source.hasNext()) source.next() else error("Please dont pass empty iterators in here")
// The reason we need this marker is that our iterator can still hold one value, even if the source has been drained.
private var hasNext = true
override fun hasNext() = hasNext
override tailrec fun next(): T {
if (!source.hasNext()) {
hasNext = false
return previous
}
val current = source.next()
val merged = merger(previous, current)
// If the elements cant be merged, return the first, then save the second for next time.
return if (merged == null) {
val ret = previous
previous = current
ret
} else {
previous = merged
next()
}
}
}
}