diff --git a/src/main/kotlin/moe/kageru/sekwences/CoalescingSequence.kt b/src/main/kotlin/moe/kageru/sekwences/CoalescingSequence.kt new file mode 100644 index 0000000..161c19c --- /dev/null +++ b/src/main/kotlin/moe/kageru/sekwences/CoalescingSequence.kt @@ -0,0 +1,41 @@ +package moe.kageru.sekwences + + +/** + * Sequence that holds a [CoalescingIterator]. + */ +internal class CoalescingSequence(private val source: Sequence, private inline val merger: (T, T) -> T?) : Sequence { + override fun iterator(): Iterator { + return CoalescingIterator(source.iterator(), merger) + } + + /** + * Iterator that will attempt to merge adjacent elements as described in the KDoc for [coalesce]. + */ + internal class CoalescingIterator(private val source: Iterator, private inline val merger: (T, T) -> T?) : Iterator { + private var previous: T = if (source.hasNext()) source.next() else error("Please don’t 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 can’t 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() + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/moe/kageru/sekwences/Sekwences.kt b/src/main/kotlin/moe/kageru/sekwences/Sekwences.kt index eb0a019..6284abc 100644 --- a/src/main/kotlin/moe/kageru/sekwences/Sekwences.kt +++ b/src/main/kotlin/moe/kageru/sekwences/Sekwences.kt @@ -18,42 +18,3 @@ fun Sequence.coalesce(merger: (T, T) -> T?): Sequence { emptySequence() } } - -/** - * Sequence that holds a [CoalescingIterator]. - */ -internal class CoalescingSequence(private val source: Sequence, private inline val merger: (T, T) -> T?) : Sequence { - override fun iterator(): Iterator { - return CoalescingIterator(source.iterator(), merger) - } -} - -/** - * Iterator that will attempt to merge adjacent elements as described in the KDoc for [coalesce]. - */ -internal class CoalescingIterator(private val source: Iterator, private inline val merger: (T, T) -> T?) : Iterator { - private var previous: T = if (source.hasNext()) source.next() else error("Please don’t 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 can’t 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() - } - } -}