diff --git a/libraries/stdlib/src/generated/_Elements.kt b/libraries/stdlib/src/generated/_Elements.kt index d57c2d248ce..26a6543af20 100644 --- a/libraries/stdlib/src/generated/_Elements.kt +++ b/libraries/stdlib/src/generated/_Elements.kt @@ -600,9 +600,9 @@ public inline fun ShortArray.elementAtOrElse(index: Int, defaultValue: (Int) -> /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. */ -public inline fun Iterable.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T { +public fun Iterable.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T { if (this is List) - return this.elementAtOrElse(index, defaultValue) + return this.getOrElse(index, defaultValue) if (index < 0) return defaultValue(index) val iterator = iterator() @@ -625,7 +625,7 @@ public inline fun List.elementAtOrElse(index: Int, defaultValue: (Int) -> /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. */ -public inline fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T { +public fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T { if (index < 0) return defaultValue(index) val iterator = iterator() @@ -713,7 +713,7 @@ public fun ShortArray.elementAtOrNull(index: Int): Short? { */ public fun Iterable.elementAtOrNull(index: Int): T? { if (this is List) - return this.elementAtOrNull(index) + return this.getOrNull(index) if (index < 0) return null val iterator = iterator() @@ -1229,6 +1229,160 @@ public inline fun String.firstOrNull(predicate: (Char) -> Boolean): Char? { return null } +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun Array.getOrElse(index: Int, defaultValue: (Int) -> T): T { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun BooleanArray.getOrElse(index: Int, defaultValue: (Int) -> Boolean): Boolean { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun ByteArray.getOrElse(index: Int, defaultValue: (Int) -> Byte): Byte { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun CharArray.getOrElse(index: Int, defaultValue: (Int) -> Char): Char { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun DoubleArray.getOrElse(index: Int, defaultValue: (Int) -> Double): Double { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun FloatArray.getOrElse(index: Int, defaultValue: (Int) -> Float): Float { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun IntArray.getOrElse(index: Int, defaultValue: (Int) -> Int): Int { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun LongArray.getOrElse(index: Int, defaultValue: (Int) -> Long): Long { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun ShortArray.getOrElse(index: Int, defaultValue: (Int) -> Short): Short { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun List.getOrElse(index: Int, defaultValue: (Int) -> T): T { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection. + */ +public inline fun String.getOrElse(index: Int, defaultValue: (Int) -> Char): Char { + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun Array.getOrNull(index: Int): T? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun BooleanArray.getOrNull(index: Int): Boolean? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun ByteArray.getOrNull(index: Int): Byte? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun CharArray.getOrNull(index: Int): Char? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun DoubleArray.getOrNull(index: Int): Double? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun FloatArray.getOrNull(index: Int): Float? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun IntArray.getOrNull(index: Int): Int? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun LongArray.getOrNull(index: Int): Long? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun ShortArray.getOrNull(index: Int): Short? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun List.getOrNull(index: Int): T? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + +/** + * Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection. + */ +public fun String.getOrNull(index: Int): Char? { + return if (index >= 0 && index <= lastIndex) get(index) else null +} + /** * Returns first index of [element], or -1 if the collection does not contain element. */ diff --git a/libraries/stdlib/test/collections/ListSpecificTest.kt b/libraries/stdlib/test/collections/ListSpecificTest.kt index 2e136584390..b494c742724 100644 --- a/libraries/stdlib/test/collections/ListSpecificTest.kt +++ b/libraries/stdlib/test/collections/ListSpecificTest.kt @@ -28,6 +28,22 @@ class ListSpecificTest { assertEquals(listOf('C', 'A', 'D'), list.slice(iter)) } + Test fun getOr() { + expect("foo") { data.get(0) } + expect("bar") { data.get(1) } + fails { data.get(2) } + fails { data.get(-1) } + fails { empty.get(0) } + + expect("foo") { data.getOrElse(0, {""} )} + expect("zoo") { data.getOrElse(-1, { "zoo" })} + expect("zoo") { data.getOrElse(2, { "zoo" })} + expect("zoo") { empty.getOrElse(0) { "zoo" }} + + expect(null) { empty.getOrNull(0) } + + } + Test fun lastIndex() { assertEquals(-1, empty.lastIndex) assertEquals(1, data.lastIndex) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt index 1a1553ee019..c05cfece09e 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt @@ -202,11 +202,10 @@ fun elements(): List { templates add f("elementAtOrElse(index: Int, defaultValue: (Int) -> T)") { doc { "Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection." } returns("T") - inline(true) body { """ if (this is List) - return this.elementAtOrElse(index, defaultValue) + return this.getOrElse(index, defaultValue) if (index < 0) return defaultValue(index) val iterator = iterator() @@ -233,6 +232,7 @@ fun elements(): List { return defaultValue(index) """ } + inline(true, Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) body(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) { """ return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) @@ -240,6 +240,18 @@ fun elements(): List { } } + templates add f("getOrElse(index: Int, defaultValue: (Int) -> T)") { + doc { "Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection." } + returns("T") + inline(true) + only(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) + body { + """ + return if (index >= 0 && index <= lastIndex) get(index) else defaultValue(index) + """ + } + } + templates add f("elementAtOrNull(index: Int)") { doc { "Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection." } @@ -247,7 +259,7 @@ fun elements(): List { body { """ if (this is List) - return this.elementAtOrNull(index) + return this.getOrNull(index) if (index < 0) return null val iterator = iterator() @@ -281,6 +293,18 @@ fun elements(): List { } } + templates add f("getOrNull(index: Int)") { + doc { "Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection." } + returns("T?") + only(Strings, Lists, ArraysOfObjects, ArraysOfPrimitives) + body { + """ + return if (index >= 0 && index <= lastIndex) get(index) else null + """ + } + } + + templates add f("first()") { doc { """Returns first element. @throws [NoSuchElementException] if the collection is empty.