diff --git a/libraries/stdlib/src/generated/_Arrays.kt b/libraries/stdlib/src/generated/_Arrays.kt index 3cd3de83239..f611a3055e4 100644 --- a/libraries/stdlib/src/generated/_Arrays.kt +++ b/libraries/stdlib/src/generated/_Arrays.kt @@ -226,6 +226,32 @@ public inline fun > Array.mapTo(result: return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun > Array.max() : T? { + var max: T? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun > Array.min() : T? { + var min: T? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_ByteArrays.kt b/libraries/stdlib/src/generated/_ByteArrays.kt index 3fd3ea83b1a..564baba18af 100644 --- a/libraries/stdlib/src/generated/_ByteArrays.kt +++ b/libraries/stdlib/src/generated/_ByteArrays.kt @@ -211,6 +211,32 @@ public inline fun > ByteArray.mapTo(result: C, tra return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun ByteArray.max() : Byte? { + var max: Byte? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun ByteArray.min() : Byte? { + var min: Byte? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_DoubleArrays.kt b/libraries/stdlib/src/generated/_DoubleArrays.kt index 763c5951a46..13cf48ac2b1 100644 --- a/libraries/stdlib/src/generated/_DoubleArrays.kt +++ b/libraries/stdlib/src/generated/_DoubleArrays.kt @@ -211,6 +211,32 @@ public inline fun > DoubleArray.mapTo(result: C, t return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun DoubleArray.max() : Double? { + var max: Double? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun DoubleArray.min() : Double? { + var min: Double? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_FloatArrays.kt b/libraries/stdlib/src/generated/_FloatArrays.kt index 7599332272f..b0070e7ba04 100644 --- a/libraries/stdlib/src/generated/_FloatArrays.kt +++ b/libraries/stdlib/src/generated/_FloatArrays.kt @@ -211,6 +211,32 @@ public inline fun > FloatArray.mapTo(result: C, tr return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun FloatArray.max() : Float? { + var max: Float? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun FloatArray.min() : Float? { + var min: Float? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_IntArrays.kt b/libraries/stdlib/src/generated/_IntArrays.kt index 905a729e37c..3c29aac0001 100644 --- a/libraries/stdlib/src/generated/_IntArrays.kt +++ b/libraries/stdlib/src/generated/_IntArrays.kt @@ -211,6 +211,32 @@ public inline fun > IntArray.mapTo(result: C, tran return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun IntArray.max() : Int? { + var max: Int? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun IntArray.min() : Int? { + var min: Int? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_Iterables.kt b/libraries/stdlib/src/generated/_Iterables.kt index f7eaad52822..afb3bdf5b65 100644 --- a/libraries/stdlib/src/generated/_Iterables.kt +++ b/libraries/stdlib/src/generated/_Iterables.kt @@ -212,6 +212,32 @@ public inline fun > Iterable.mapTo(result: C return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun > Iterable.max() : T? { + var max: T? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun > Iterable.min() : T? { + var min: T? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_Iterators.kt b/libraries/stdlib/src/generated/_Iterators.kt index 1d7efb5ae79..2b1e518840c 100644 --- a/libraries/stdlib/src/generated/_Iterators.kt +++ b/libraries/stdlib/src/generated/_Iterators.kt @@ -212,6 +212,32 @@ public inline fun > Iterator.mapTo(result: C return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun > Iterator.max() : T? { + var max: T? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun > Iterator.min() : T? { + var min: T? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_LongArrays.kt b/libraries/stdlib/src/generated/_LongArrays.kt index fd15d7dfa8e..8632cf9c70b 100644 --- a/libraries/stdlib/src/generated/_LongArrays.kt +++ b/libraries/stdlib/src/generated/_LongArrays.kt @@ -211,6 +211,32 @@ public inline fun > LongArray.mapTo(result: C, tra return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun LongArray.max() : Long? { + var max: Long? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun LongArray.min() : Long? { + var min: Long? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/src/generated/_ShortArrays.kt b/libraries/stdlib/src/generated/_ShortArrays.kt index 3264f52d3fd..28ce9c80618 100644 --- a/libraries/stdlib/src/generated/_ShortArrays.kt +++ b/libraries/stdlib/src/generated/_ShortArrays.kt @@ -211,6 +211,32 @@ public inline fun > ShortArray.mapTo(result: C, tr return result } +/** + * Returns the largest element or null if there are no elements + */ +public fun ShortArray.max() : Short? { + var max: Short? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max +} + +/** + * Returns the smallest element or null if there are no elements + */ +public fun ShortArray.min() : Short? { + var min: Short? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min +} + /** * Partitions this collection into a pair of collections */ diff --git a/libraries/stdlib/test/ArraysJVMTest.kt b/libraries/stdlib/test/ArraysJVMTest.kt index d18dd149d7f..ee17a4fad62 100644 --- a/libraries/stdlib/test/ArraysJVMTest.kt +++ b/libraries/stdlib/test/ArraysJVMTest.kt @@ -59,6 +59,28 @@ class ArraysJVMTest { } } + test fun min() { + expect(null, { intArray().min() }) + expect(1, { intArray(1).min() }) + expect(2, { intArray(2, 3).min() }) + expect(2000000000000, { longArray(3000000000000, 2000000000000).min() }) + expect(1, { byteArray(1, 3, 2).min() }) + expect(2, { shortArray(3, 2).min() }) + expect(2.0, { floatArray(3.0, 2.0).min() }) + expect(2.0, { doubleArray(2.0, 3.0).min() }) + } + + test fun max() { + expect(null, { intArray().max() }) + expect(1, { intArray(1).max() }) + expect(3, { intArray(2, 3).max() }) + expect(3000000000000, { longArray(3000000000000, 2000000000000).max() }) + expect(3, { byteArray(1, 3, 2).max() }) + expect(3, { shortArray(3, 2).max() }) + expect(3.0, { floatArray(3.0, 2.0).max() }) + expect(3.0, { doubleArray(2.0, 3.0).max() }) + } + test fun sum() { expect(0) { intArray().sum() } expect(14) { intArray(2, 3, 9).sum() } diff --git a/libraries/stdlib/test/ArraysTest.kt b/libraries/stdlib/test/ArraysTest.kt index 7e90d0a1adf..5f99cedb92b 100644 --- a/libraries/stdlib/test/ArraysTest.kt +++ b/libraries/stdlib/test/ArraysTest.kt @@ -101,6 +101,24 @@ class ArraysTest { assertEquals(false, arr[1]) } + test fun min() { + expect(null, { array().min() }) + expect(1, { array(1).min() }) + expect(2, { array(2, 3).min() }) + expect(2000000000000, { array(3000000000000, 2000000000000).min() }) + expect('a', { array('a', 'b').min() }) + expect("a", { array("a", "b").min() }) + } + + test fun max() { + expect(null, { array().max() }) + expect(1, { array(1).max() }) + expect(3, { array(2, 3).max() }) + expect(3000000000000, { array(3000000000000, 2000000000000).max() }) + expect('b', { array('a', 'b').max() }) + expect("b", { array("a", "b").max() }) + } + test fun sum() { expect(0) { array().sum() } expect(14) { array(2, 3, 9).sum() } diff --git a/libraries/stdlib/test/CollectionTest.kt b/libraries/stdlib/test/CollectionTest.kt index 0d37ba4c0eb..69f41c5f2f6 100644 --- a/libraries/stdlib/test/CollectionTest.kt +++ b/libraries/stdlib/test/CollectionTest.kt @@ -414,6 +414,28 @@ class CollectionTest { expect(arrayList(2, 3, 1)) { list } } + test fun min() { + expect(null, { listOf().min() }) + expect(1, { listOf(1).min() }) + expect(2, { listOf(2, 3).min() }) + expect(2000000000000, { listOf(3000000000000, 2000000000000).min() }) + expect('a', { listOf('a', 'b').min() }) + expect("a", { listOf("a", "b").min() }) + expect(null, { listOf().iterator().min() }) + expect(2, { listOf(2, 3).iterator().min() }) + } + + test fun max() { + expect(null, { listOf().max() }) + expect(1, { listOf(1).max() }) + expect(3, { listOf(2, 3).max() }) + expect(3000000000000, { listOf(3000000000000, 2000000000000).max() }) + expect('b', { listOf('a', 'b').max() }) + expect("b", { listOf("a", "b").max() }) + expect(null, { listOf().iterator().max() }) + expect(3, { listOf(2, 3).iterator().max() }) + } + test fun sum() { expect(0) { ArrayList().sum() } expect(14) { arrayListOf(2, 3, 9).sum() } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Commons.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Commons.kt index 0eb638160d3..1c1f7dbbc17 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Commons.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Commons.kt @@ -407,6 +407,44 @@ fun commons(): ArrayList { } } + templates add f("min()") { + doc = "Returns the smallest element or null if there are no elements" + returns("T?") + absentFor(PrimitiveType.Boolean, PrimitiveType.Char)//currently there are no sane way to compare Char? with something (KT-4251) + typeParam("T: Comparable") + isInline = false + body { + """ + var min: T? = null + for (e in this) { + if (min == null || min!! > e) { + min = e + } + } + return min + """ + } + } + + templates add f("max()") { + doc = "Returns the largest element or null if there are no elements" + returns("T?") + absentFor(PrimitiveType.Boolean, PrimitiveType.Char)//currently there are no sane way to compare Char? with something (KT-4251) + typeParam("T: Comparable") + isInline = false + body { + """ + var max: T? = null + for (e in this) { + if (max == null || max!! < e) { + max = e + } + } + return max + """ + } + } + templates add f("appendString(buffer: Appendable, separator: String = \", \", prefix: String =\"\", postfix: String = \"\", limit: Int = -1, truncated: String = \"...\")") { doc = """ diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt index 23c388ead4b..88be3c3f0ea 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt @@ -21,6 +21,7 @@ class GenericFunction(val signature : String): Comparable { var isInline : Boolean = true; private val customReceivers = HashMap() val blockedFor = HashSet() + private val blockedForPrimitive = HashSet() val bodies = HashMap() val returnTypes = HashMap() val typeParams = ArrayList() @@ -57,6 +58,10 @@ class GenericFunction(val signature : String): Comparable { blockedFor.addAll(f.toList()) } + fun absentFor(vararg p: PrimitiveType) { + blockedForPrimitive.addAll(p.toList()) + } + private fun effectiveTypeParams(f : Family) : List { val types = ArrayList(typeParams) if (typeParams.find { it.startsWith("T") } == null && !customReceivers.containsKey(f)) { @@ -74,6 +79,7 @@ class GenericFunction(val signature : String): Comparable { fun buildFor(f: Family, primitiveType: PrimitiveType?) : String { if (blockedFor.contains(f)) return "" + if (primitiveType != null && blockedForPrimitive.contains(primitiveType)) return "" if (returnTypes[f] == null) throw RuntimeException("No return type specified for $signature") val retType = returnTypes[f]!!