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 if (nextIterator!!.hasNext()) return true else nextIterator = null
State_Done -> return false State_Done -> return false
State_Ready -> return true State_Ready -> return true
else -> throw unexpectedState() else -> throw exceptionalState()
} }
state = State_Failed 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) { when (state) {
State_NotReady -> if (!hasNext()) throw NoSuchElementException() else return next() State_NotReady -> return nextNotReady()
State_ManyReady -> { State_ManyReady -> return nextIterator!!.next()
val iterator = nextIterator!!
return iterator.next()
}
State_Ready -> { State_Ready -> {
state = State_NotReady state = State_NotReady
val result = nextValue as T val result = nextValue as T
nextValue = null nextValue = null
return result return result
} }
State_Done -> throw NoSuchElementException() else -> throw exceptionalState()
else -> throw unexpectedState()
} }
} }
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) { suspend override fun yield(value: T) {
@@ -35,7 +35,7 @@ class SequenceBuilderTest {
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException) assertFailsWith<NoSuchElementException> { iterator.next() }
} }
@Test @Test
@@ -61,7 +61,7 @@ class SequenceBuilderTest {
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException) assertFailsWith<NoSuchElementException> { iterator.next() }
assertEquals(1, result.iterator().next()) assertEquals(1, result.iterator().next())
} }
@@ -74,7 +74,7 @@ class SequenceBuilderTest {
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException) assertFailsWith<NoSuchElementException> { iterator.next() }
} }
@Test @Test
@@ -106,7 +106,7 @@ class SequenceBuilderTest {
sharedVar = -1 sharedVar = -1
assertFalse(iterator.hasNext()) assertFalse(iterator.hasNext())
assertTrue(assertFails { iterator.next() } is NoSuchElementException) assertFailsWith<NoSuchElementException> { iterator.next() }
} }
@Test @Test
@@ -116,7 +116,7 @@ class SequenceBuilderTest {
while (true) { while (true) {
when (sharedVar) { when (sharedVar) {
-1 -> return@buildSequence -1 -> return@buildSequence
-2 -> error("Invalid state: -2") -2 -> throw UnsupportedOperationException("-2 is unsupported")
else -> yield(sharedVar) else -> yield(sharedVar)
} }
} }
@@ -128,7 +128,9 @@ class SequenceBuilderTest {
assertEquals(1, iterator.next()) assertEquals(1, iterator.next())
sharedVar = -2 sharedVar = -2
assertTrue(assertFails { iterator.hasNext() } is IllegalStateException) assertFailsWith<UnsupportedOperationException> { iterator.hasNext() }
assertFailsWith<IllegalStateException> { iterator.hasNext() }
assertFailsWith<IllegalStateException> { iterator.next() }
} }
@Test @Test