diff --git a/stdlib/ktSrc/JavaIterablesSpecial.kt b/stdlib/ktSrc/JavaIterablesSpecial.kt index 3a564fabeb8..e0b301f7e3a 100644 --- a/stdlib/ktSrc/JavaIterablesSpecial.kt +++ b/stdlib/ktSrc/JavaIterablesSpecial.kt @@ -1,9 +1,10 @@ package std.util -// Number of extension function for ava.lang.Iterable that shouldn't participate in auto generation +// Number of extension function for java.lang.Iterable that shouldn't participate in auto generation import java.util.Collection import java.util.List import java.util.AbstractList +import java.util.Iterator /** * Count the number of elements in collection. @@ -83,3 +84,38 @@ fun java.lang.Iterable.contains(item : T) : Boolean { return false } + +/** + * Convert collection of arbitrary elements to collection of + */ +fun java.lang.Iterable.withIndices() : java.lang.Iterable<#(Int, T)> { + return object : java.lang.Iterable<#(Int, T)> { + override fun iterator(): java.util.Iterator<#(Int, T)> { + // TODO explicit typecast as a workaround for KT-1457, should be removed when it is fixed + return NumberedIterator(this@withIndices.iterator().sure()) as java.util.Iterator<#(Int, T)> + } + } +} + +private class NumberedIterator(private val sourceIterator : java.util.Iterator) : java.util.Iterator<#(Int, TT)> { + private var nextIndex = 0 + + override fun remove() { + try { + sourceIterator.remove() + nextIndex--; + } catch (e : UnsupportedOperationException) { + throw e + } + } + + override fun hasNext(): Boolean { + return sourceIterator.hasNext(); + } + + override fun next(): #(Int, TT) { + val result = #(nextIndex, sourceIterator.next()) + nextIndex++ + return result + } +} \ No newline at end of file diff --git a/testlib/test/ListTest.kt b/testlib/test/ListTest.kt index e45177d4d91..8fb628735db 100644 --- a/testlib/test/ListTest.kt +++ b/testlib/test/ListTest.kt @@ -27,4 +27,15 @@ class ListTest() : TestSupport() { val t = data.last assertEquals("bar", t) } + + fun testWithIndices() { + val withIndices = data.withIndices() + var index = 0 + for (withIndex in withIndices) { + assertEquals(withIndex._1, index) + assertEquals(withIndex._2, data[index]) + index++ + } + assertEquals(data.size(), index) + } }