Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions libraries/stdlib/common/src/generated/_Arrays.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,16 @@ public inline fun CharArray.find(predicate: (Char) -> Boolean): Char? {
return firstOrNull(predicate)
}

/**
* Returns the first transformed element matching specified type parameter R, or `null` if no such element was found.
*
* @sample samples.collections.Collections.Elements.findIs
*/
@kotlin.internal.InlineOnly
public inline fun <reified R> Array<*>.findIs(): R? {
return find { element -> element is R } as R?
}

/**
* Returns the last element matching the given [predicate], or `null` if no such element was found.
*
Expand Down Expand Up @@ -1301,6 +1311,16 @@ public inline fun CharArray.first(predicate: (Char) -> Boolean): Char {
throw NoSuchElementException("Array contains no element matching the predicate.")
}

/**
* Returns the first element matching the specified type R.
* @throws [NoSuchElementException] if no such element of specified type R is found.
*/
@kotlin.internal.InlineOnly
public inline fun <reified R> Array<*>.firstIs(): R? {
for (element in this) if (element is R) return element
throw NoSuchElementException("Array contains no element matching the specified type ${R::class.simpleName}.")
}

/**
* Returns the first non-null value produced by [transform] function being applied to elements of this array in iteration order,
* or throws [NoSuchElementException] if no non-null value was produced.
Expand Down
20 changes: 20 additions & 0 deletions libraries/stdlib/common/src/generated/_Collections.kt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}

/**
* Returns the first transformed element matching specified type parameter R, or `null` if no such element was found.
*
* @sample samples.collections.Collections.Elements.findIs
*/
@kotlin.internal.InlineOnly
public inline fun <reified R> Iterable<*>.findIs(): R? {
return find { element -> element is R } as R?
}

/**
* Returns the last element matching the given [predicate], or `null` if no such element was found.
*
Expand Down Expand Up @@ -232,6 +242,16 @@ public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T {
throw NoSuchElementException("Collection contains no element matching the predicate.")
}

/**
* Returns the first element matching the specified type R.
* @throws [NoSuchElementException] if no such element of specified type R is found.
*/
@kotlin.internal.InlineOnly
public inline fun <reified R> Iterable<*>.firstIs(): R? {
for (element in this) if (element is R) return element
throw NoSuchElementException("Collection contains no element matching the specified type ${R::class.simpleName}.")
}

/**
* Returns the first non-null value produced by [transform] function being applied to elements of this collection in iteration order,
* or throws [NoSuchElementException] if no non-null value was produced.
Expand Down
24 changes: 24 additions & 0 deletions libraries/stdlib/common/src/generated/_Sequences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ public inline fun <T> Sequence<T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}

/**
* Returns the first transformed element matching specified type parameter R, or `null` if no such element was found.
*
* The operation is _terminal_.
*
* @sample samples.collections.Collections.Elements.findIs
*/
@kotlin.internal.InlineOnly
public inline fun <reified R> Sequence<*>.findIs(): R? {
return find { element -> element is R } as R?
}

/**
* Returns the last element matching the given [predicate], or `null` if no such element was found.
*
Expand Down Expand Up @@ -129,6 +141,18 @@ public inline fun <T> Sequence<T>.first(predicate: (T) -> Boolean): T {
throw NoSuchElementException("Sequence contains no element matching the predicate.")
}

/**
* Returns the first element matching the specified type R.
* @throws [NoSuchElementException] if no such element of specified type R is found.
*
* The operation is _terminal_.
*/
@kotlin.internal.InlineOnly
public inline fun <reified R> Sequence<*>.firstIs(): R? {
for (element in this) if (element is R) return element
throw NoSuchElementException("Sequence contains no element matching the specified type ${R::class.simpleName}.")
}

/**
* Returns the first non-null value produced by [transform] function being applied to elements of this sequence in iteration order,
* or throws [NoSuchElementException] if no non-null value was produced.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,43 @@ class Collections {
assertPrints(lastEven, "6")
}

@Sample
fun findIs() {
val objects = listOf<Any?>("one", 1, true, null)
val string = objects.findIs<String>()
val boolean = objects.findIs<Boolean>()
val number = objects.findIs<Number>()
val int = objects.findIs<Int>()
val long = objects.findIs<Long>()

assertPrints(string, "one")
assertEquals(number, 1)
assertEquals(int, 1)
assertTrue { boolean == true }
assertNull(long)
}

@Sample
fun firstIs() {
val objects = listOf<Any?>("one", 1, true, null)
val string = objects.firstIs<String>()
val boolean = objects.firstIs<Boolean>()
val number = objects.firstIs<Number>()
val int = objects.firstIs<Int>()

assertPrints(string, "one")
assertEquals(number, 1)
assertEquals(int, 1)
assertTrue { boolean == true }

val exception = assertFails {
objects.firstIs<Long>()
}

assertIs<NoSuchElementException>(exception)
assertEquals("Collection contains no element matching the specified type Long.", exception.message)
}

@Sample
fun getOrElse() {
val list = listOf(1, 2, 3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13876,6 +13876,24 @@ final inline fun <#A: kotlin/Any?> (kotlin.collections/Collection<#A>).kotlin.co
// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: kotlin/Any?> kotlin/emptyArray(): kotlin/Array<#A> // kotlin/emptyArray|emptyArray(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: reified kotlin/Any?> (kotlin.collections/Iterable<*>).kotlin.collections/findIs(): #A? // kotlin.collections/findIs|[email protected]<*>(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: reified kotlin/Any?> (kotlin.collections/Iterable<*>).kotlin.collections/firstIs(): #A? // kotlin.collections/firstIs|[email protected]<*>(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: reified kotlin/Any?> (kotlin.sequences/Sequence<*>).kotlin.sequences/findIs(): #A? // kotlin.sequences/findIs|[email protected]<*>(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: reified kotlin/Any?> (kotlin.sequences/Sequence<*>).kotlin.sequences/firstIs(): #A? // kotlin.sequences/firstIs|[email protected]<*>(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: reified kotlin/Any?> (kotlin/Array<*>).kotlin.collections/findIs(): #A? // kotlin.collections/findIs|[email protected]<*>(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs, wasmWasi]
final inline fun <#A: reified kotlin/Any?> (kotlin/Array<*>).kotlin.collections/firstIs(): #A? // kotlin.collections/firstIs|[email protected]<*>(){0§<kotlin.Any?>}[0]

// Targets: [js, wasmJs]
open annotation class kotlin.js/ExperimentalWasmJsInterop : kotlin/Annotation { // kotlin.js/ExperimentalWasmJsInterop|null[0]
constructor <init>() // kotlin.js/ExperimentalWasmJsInterop.<init>|<init>(){}[0]
Expand Down
39 changes: 39 additions & 0 deletions libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,25 @@ object Elements : TemplateGroupBase() {
}
}

val f_firstIs = fn("firstIs()") {
include(Iterables, Sequences, ArraysOfObjects)
} builder {
inlineOnly()
genericStarProjection = true
typeParam("reified R")
returns("R?")

doc { """Returns the first ${f.element} matching the specified type R.
@throws [NoSuchElementException] if no such ${f.element} of specified type R is found.""" }

body {
"""
for (element in this) if (element is R) return element
throw NoSuchElementException("${f.doc.collection.capitalize()} contains no ${f.doc.element} matching the specified type ${"$"}{R::class.simpleName}.")
"""
}
}

val f_find = fn("find(predicate: (T) -> Boolean)") {
includeDefault()
include(CharSequences, ArraysOfUnsigned)
Expand All @@ -627,6 +646,26 @@ object Elements : TemplateGroupBase() {
body { "return firstOrNull(predicate)"}
}

val f_findIs = fn("findIs()") {
include(Iterables, Sequences, ArraysOfObjects)
} builder {
inlineOnly()
genericStarProjection = true
typeParam("reified R")
returns("R?")

sample("samples.collections.Collections.Elements.findIs")

doc {
"Returns the first transformed ${f.element} matching specified type parameter R, or `null` if no such ${f.element} was found."
}
body {
"""
return find { element -> element is R } as R?
"""
}
}

private val Family.sampleClass: String
get() = when (this) {
Strings, CharSequences -> "samples.text.Strings"
Expand Down