Skip to content

Commit fe58e7d

Browse files
committed
Add persistent Collection builder functions
1 parent 6cf38bc commit fe58e7d

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

core/commonMain/src/extensions.kt

+53
Original file line numberDiff line numberDiff line change
@@ -766,3 +766,56 @@ fun <K, V> Map<K, V>.toPersistentHashMap(): PersistentMap<K, V>
766766
= this as? PersistentHashMap
767767
?: (this as? PersistentHashMapBuilder<K, V>)?.build()
768768
?: PersistentHashMap.emptyOf<K, V>().putAll(this)
769+
770+
/**
771+
* Returns an immutable list using the given [builderAction]
772+
*
773+
* The list passed as a receiver to the [builderAction] is valid only inside that function.
774+
* Using it outside the function produces an unspecified behavior.
775+
*/
776+
inline fun <T> buildPersistentList(builderAction: PersistentList.Builder<T>.() -> Unit): PersistentList<T> =
777+
persistentListOf<T>().builder().apply(builderAction).build()
778+
779+
/**
780+
* Returns an immutable set using the given [builderAction]
781+
*
782+
* The list passed as a receiver to the [builderAction] is valid only inside that function.
783+
* Using it outside the function produces an unspecified behavior.
784+
*
785+
* Elements of the set are iterated in the order they were added by the [builderAction].
786+
*/
787+
inline fun <T> buildPersistentSet(builderAction: PersistentSet.Builder<T>.() -> Unit): PersistentSet<T> =
788+
persistentSetOf<T>().builder().apply(builderAction).build()
789+
790+
/**
791+
* Returns an immutable hash set using the given [builderAction]
792+
*
793+
* The list passed as a receiver to the [builderAction] is valid only inside that function.
794+
* Using it outside the function produces an unspecified behavior.
795+
*
796+
* Order of the elements in the returned set is unspecified.
797+
*/
798+
inline fun <T> buildPersistentHashSet(builderAction: PersistentSet.Builder<T>.() -> Unit): PersistentSet<T> =
799+
persistentHashSetOf<T>().builder().apply(builderAction).build()
800+
801+
/**
802+
* Returns an immutable map using the given [builderAction]
803+
*
804+
* The map passed as a receiver to the [builderAction] is valid only inside that function.
805+
* Using it outside the function produces an unspecified behavior.
806+
*
807+
* Entries of the map are iterated in the order they were added by the [builderAction].
808+
*/
809+
inline fun <K, V> buildPersistentMap(builderAction: PersistentMap.Builder<K, V>.() -> Unit): PersistentMap<K, V> =
810+
persistentMapOf<K, V>().builder().apply(builderAction).build()
811+
812+
/**
813+
* Returns an immutable hash map using the given [builderAction]
814+
*
815+
* The map passed as a receiver to the [builderAction] is valid only inside that function.
816+
* Using it outside the function produces an unspecified behavior.
817+
*
818+
* Order of the entries in the returned map is unspecified.
819+
*/
820+
inline fun <K, V> buildPersistentHashMap(builderAction: PersistentMap.Builder<K, V>.() -> Unit): PersistentMap<K, V> =
821+
persistentHashMapOf<K, V>().builder().apply(builderAction).build()

core/commonTest/src/contract/list/ImmutableListTest.kt

+10
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ class ImmutableListTest {
152152
}
153153
}
154154

155+
@Test fun buildPersistentList() {
156+
val expected = persistentListOf(1, 2, 3, 4, 5, 6)
157+
val actual = buildPersistentList {
158+
for (i in 1..6) {
159+
add(i)
160+
}
161+
}
162+
assertEquals(expected, actual)
163+
}
164+
155165
@Test fun subListOfBuilder() {
156166
val list = "abcxaxyz12".toImmutableList().toPersistentList()
157167
val builder = list.builder()

core/commonTest/src/contract/map/ImmutableMapTest.kt

+30
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ class ImmutableHashMapTest : ImmutableMapTest() {
7878
compareMaps(expected, builder1.build())
7979
}
8080

81+
@Test fun buildPersistentHashMap() {
82+
val expected = mutableMapOf<String, Int>()
83+
val actual = buildPersistentHashMap {
84+
for (i in 300..400) {
85+
put("$i", i)
86+
expected["$i"] = i
87+
}
88+
for (i in 0..200) {
89+
put("$i", i)
90+
expected["$i"] = i
91+
}
92+
}
93+
compareMapsUnordered(expected, actual)
94+
}
95+
8196
@Test fun regressionGithubIssue109() {
8297
// https://github.com/Kotlin/kotlinx.collections.immutable/issues/109
8398
val map0 = immutableMapOf<Int, Int>().put(0, 0).put(1, 1).put(32, 32)
@@ -139,6 +154,21 @@ class ImmutableOrderedMapTest : ImmutableMapTest() {
139154
changing.add("break iteration")
140155
assertFailsWith<ConcurrentModificationException> { builder.filter { it.key === changing } }
141156
}
157+
158+
@Test fun buildPersistentMap() {
159+
val expected = mutableMapOf<String, Int>()
160+
val actual = buildPersistentMap {
161+
for (i in 300..400) {
162+
put("$i", i)
163+
expected["$i"] = i
164+
}
165+
for (i in 0..200) {
166+
put("$i", i)
167+
expected["$i"] = i
168+
}
169+
}
170+
compareMaps(expected, actual)
171+
}
142172
}
143173

144174
abstract class ImmutableMapTest {

core/commonTest/src/contract/set/ImmutableSetTest.kt

+22
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,17 @@ class ImmutableHashSetTest : ImmutableSetTestBase() {
195195
compareSets(immutableSetOf<Int>(), left - right)
196196
}
197197
}
198+
199+
@Test fun buildPersistentHashSet() {
200+
val expected = mutableSetOf<Int>()
201+
val actual = buildPersistentHashSet {
202+
for (i in 0..2000) {
203+
add(i)
204+
expected.add(i)
205+
}
206+
}
207+
compareSetsUnordered(expected, actual)
208+
}
198209
}
199210

200211
class ImmutableOrderedSetTest : ImmutableSetTestBase() {
@@ -221,6 +232,17 @@ class ImmutableOrderedSetTest : ImmutableSetTestBase() {
221232
changing.add("break iteration")
222233
assertFailsWith<ConcurrentModificationException> { builder.filter { it === changing } }
223234
}
235+
236+
@Test fun buildPersistentSet() {
237+
val expected = mutableSetOf<Int>()
238+
val actual = buildPersistentSet {
239+
for (i in 0..2000) {
240+
add(i)
241+
expected.add(i)
242+
}
243+
}
244+
compareSets(expected, actual)
245+
}
224246
}
225247

226248
abstract class ImmutableSetTestBase {

0 commit comments

Comments
 (0)