Skip to content

Commit 2aff6af

Browse files
committed
Fix invalid iterator implementation of ImmutableOrderedMap builder
Fixes #18
1 parent de170b0 commit 2aff6af

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/ImmutableOrderedMap.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,15 @@ internal class ImmutableOrderedMap<K, out V> private constructor(private val imp
113113

114114
override fun iterator() = object : MutableIterator<MutableMap.MutableEntry<K, V>> {
115115
private var snapshot = impl
116-
private var entry: LinkedEntry<K,V>? = impl.firstEntry()
116+
private var nextEntry: LinkedEntry<K, V>? = impl.firstEntry()
117+
private var currentEntry: LinkedEntry<K, V>? = null
117118

118-
override fun hasNext(): Boolean = entry != null
119+
override fun hasNext(): Boolean = nextEntry != null
119120
override fun next(): MutableMap.MutableEntry<K, V> {
120121
checkForComodification()
121-
val entry = this.entry ?: throw NoSuchElementException()
122-
this.entry = snapshot[entry.nextKey]
122+
val entry = this.nextEntry ?: throw NoSuchElementException()
123+
this.nextEntry = snapshot[entry.nextKey]
124+
this.currentEntry = entry
123125
return object : MutableMap.MutableEntry<K, V>, Map.Entry<K, V> by entry.mapEntry {
124126
override fun setValue(newValue: V): V {
125127
checkForComodification()
@@ -131,10 +133,10 @@ internal class ImmutableOrderedMap<K, out V> private constructor(private val imp
131133
}
132134

133135
override fun remove() {
134-
checkNotNull(entry)
136+
val currentEntry = checkNotNull(currentEntry)
135137
checkForComodification()
136-
this@Builder.remove(entry!!.key)
137-
entry = null
138+
this@Builder.remove(currentEntry.key)
139+
this.currentEntry = null
138140
snapshot = impl
139141
}
140142

kotlinx-collections-immutable/tests/src/test/kotlin/kotlinx.collections.immutable/ImmutableMapTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,20 @@ abstract class ImmutableMapTest {
109109
assertEquals(emptyMap(), map.remove("x").remove(null))
110110
}
111111

112+
@Test
113+
fun removeCollection() {
114+
val map = immutableMapOf(0 to "a", 1 to "B", 2 to "c")
115+
116+
val newMap = map - setOf(2) - sequenceOf(1)
117+
assertEquals(mapOf(0 to "a"), newMap)
118+
}
119+
120+
@Test fun removeMatching() {
121+
val map = immutableMapOf(0 to "a", 1 to "B", 2 to "c")
122+
val newMap = map.mutate { it.entries.removeAll { it.key % 2 == 0 } }
123+
assertEquals(mapOf(1 to "B"), newMap)
124+
}
125+
112126

113127
@Test fun builder() {
114128

0 commit comments

Comments
 (0)