Move a bit of bytecode out of next()

This commit is contained in:
Ilya Gorbunov
2017-01-13 19:05:55 +03:00
parent 560c184fd4
commit ffb183a2f3
2 changed files with 22 additions and 16 deletions
@@ -76,7 +76,7 @@ private class YieldingIterator<T> : SequenceBuilder<T>(), Iterator<T>, Continuat
if (nextIterator!!.hasNext()) return true else nextIterator = null
State_Done -> return false
State_Ready -> return true
else -> throw unexpectedState()
else -> throw exceptionalState()
}
state = State_Failed
@@ -86,25 +86,29 @@ private class YieldingIterator<T> : SequenceBuilder<T>(), Iterator<T>, Continuat
}
}
override tailrec fun next(): T {
override fun next(): T {
when (state) {
State_NotReady -> if (!hasNext()) throw NoSuchElementException() else return next()
State_ManyReady -> {
val iterator = nextIterator!!
return iterator.next()
}
State_NotReady -> return nextNotReady()
State_ManyReady -> return nextIterator!!.next()
State_Ready -> {
state = State_NotReady
val result = nextValue as T
nextValue = null
return result
}
State_Done -> throw NoSuchElementException()
else -> throw unexpectedState()
else -> throw exceptionalState()
}
}
private fun unexpectedState(): Throwable = IllegalStateException("Unexpected state of the iterator: $state")
private fun nextNotReady(): T {
if (!hasNext()) throw NoSuchElementException() else return next()
}
private fun exceptionalState(): Throwable = when (state) {
State_Done -> NoSuchElementException()
State_Failed -> IllegalStateException("Iterator has failed.")
else -> IllegalStateException("Unexpected state of the iterator: $state")
}
suspend override fun yield(value: T) {
@@ -35,7 +35,7 @@ class SequenceBuilderTest {
assertFalse(iterator.hasNext())
assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException)
assertFailsWith<NoSuchElementException> { iterator.next() }
}
@Test
@@ -61,7 +61,7 @@ class SequenceBuilderTest {
assertFalse(iterator.hasNext())
assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException)
assertFailsWith<NoSuchElementException> { iterator.next() }
assertEquals(1, result.iterator().next())
}
@@ -74,7 +74,7 @@ class SequenceBuilderTest {
assertFalse(iterator.hasNext())
assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException)
assertFailsWith<NoSuchElementException> { iterator.next() }
}
@Test
@@ -106,7 +106,7 @@ class SequenceBuilderTest {
sharedVar = -1
assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException)
assertFailsWith<NoSuchElementException> { iterator.next() }
}
@Test
@@ -116,7 +116,7 @@ class SequenceBuilderTest {
while (true) {
when (sharedVar) {
-1 -> return@buildSequence
-2 -> error("Invalid state: -2")
-2 -> throw UnsupportedOperationException("-2 is unsupported")
else -> yield(sharedVar)
}
}
@@ -128,7 +128,9 @@ class SequenceBuilderTest {
assertEquals(1, iterator.next())
sharedVar = -2
assertTrue(assertFails { iterator.hasNext() } is IllegalStateException)
assertFailsWith<UnsupportedOperationException> { iterator.hasNext() }
assertFailsWith<IllegalStateException> { iterator.hasNext() }
assertFailsWith<IllegalStateException> { iterator.next() }
}
@Test