Advertisement
Guest User

Untitled

a guest
Oct 24th, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.64 KB | None | 0 0
  1. package kotlinx.coroutines
  2.  
  3. import java.util.*
  4.  
  5. class RootIterator<T>(iterator: NestedIterator<T>) : AbstractIterator<T>() {
  6. private val stack = Stack<Iterator<T>>().apply { push(iterator) }
  7.  
  8. override fun computeNext() {
  9. while (true) {
  10. if (stack.isEmpty()) {
  11. done()
  12. return
  13. }
  14. val i = stack.peek()
  15. if (!i.hasNext()) {
  16. stack.pop()
  17. } else {
  18. if (i is NestedIterator<T> && i.nextNestedIterator != null) {
  19. stack.push(i.nextNestedIterator)
  20. i.next()
  21. } else {
  22. setNext(i.next())
  23. return
  24. }
  25. }
  26. }
  27. }
  28. }
  29.  
  30. interface NestedIterable<T> : Sequence<T> {
  31. fun nestedIterator(): NestedIterator<T>
  32. override fun iterator(): Iterator<T> = RootIterator(nestedIterator())
  33. }
  34.  
  35. abstract class NestedIterator<T> : AbstractIterator<T>() {
  36. var nextNestedIterator: Iterator<T>? = null
  37. private set
  38.  
  39. fun providesIterator() = hasNext() && nextNestedIterator != null
  40.  
  41. final override fun computeNext(): Unit {
  42. nextNestedIterator = null
  43. computeNextItemOrIterator()
  44. }
  45.  
  46. abstract fun computeNextItemOrIterator()
  47.  
  48. protected fun setNextIterator(iterator: Iterator<T>) {
  49. nextNestedIterator = iterator
  50. setNext(null as T) //state transfer to Ready
  51. }
  52. }
  53.  
  54. /**
  55. * Creates a Sequence object based on received coroutine [c].
  56. *
  57. * Each call of 'yield' suspend function within the coroutine lambda generates
  58. * next element of resulting sequence.
  59. */
  60. fun <T> generate(coroutine c: GeneratorController<T>.() -> Continuation<Unit>
  61. ) = object : NestedIterable<T> {
  62. override fun nestedIterator(): NestedIterator<T> {
  63. val iterator = GeneratorController<T>()
  64. iterator.setNextStep(iterator.c())
  65. return iterator
  66. }
  67. }
  68.  
  69. class GeneratorController<T> internal constructor() : NestedIterator<T>() {
  70. private lateinit var nextStep: Continuation<Unit>
  71.  
  72. override fun computeNextItemOrIterator() {
  73. nextStep.resume(Unit)
  74. }
  75.  
  76. internal fun setNextStep(step: Continuation<Unit>) {
  77. nextStep = step
  78. }
  79.  
  80. suspend fun yield(value: T, c: Continuation<Unit>) {
  81. setNext(value)
  82. setNextStep(c)
  83. }
  84.  
  85. suspend fun yieldAll(values: Sequence<T>, c: Continuation<Unit>) {
  86. setNextIterator(if (values is NestedIterable<T>)
  87. values.nestedIterator() else
  88. values.iterator())
  89. setNextStep(c)
  90. }
  91.  
  92. operator fun handleResult(result: Unit, c: Continuation<Nothing>) {
  93. done()
  94. }
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement