Merge pull request #322 from chashnikov/stdlib-min-max
standard library: 'max' and 'min' functions added (KT-3714, KT-3843, KT-3126)
This commit is contained in:
@@ -226,6 +226,32 @@ public inline fun <T, R, C: MutableCollection<in R>> Array<out T>.mapTo(result:
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest element or null if there are no elements
|
||||||
|
*/
|
||||||
|
public fun <T: Comparable<T>> Array<out T>.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 <T: Comparable<T>> Array<out T>.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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -211,6 +211,32 @@ public inline fun <R, C: MutableCollection<in R>> ByteArray.mapTo(result: C, tra
|
|||||||
return result
|
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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -211,6 +211,32 @@ public inline fun <R, C: MutableCollection<in R>> DoubleArray.mapTo(result: C, t
|
|||||||
return result
|
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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -211,6 +211,32 @@ public inline fun <R, C: MutableCollection<in R>> FloatArray.mapTo(result: C, tr
|
|||||||
return result
|
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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -211,6 +211,32 @@ public inline fun <R, C: MutableCollection<in R>> IntArray.mapTo(result: C, tran
|
|||||||
return result
|
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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -212,6 +212,32 @@ public inline fun <T, R, C: MutableCollection<in R>> Iterable<T>.mapTo(result: C
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest element or null if there are no elements
|
||||||
|
*/
|
||||||
|
public fun <T: Comparable<T>> Iterable<T>.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 <T: Comparable<T>> Iterable<T>.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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -212,6 +212,32 @@ public inline fun <T, R, C: MutableCollection<in R>> Iterator<T>.mapTo(result: C
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest element or null if there are no elements
|
||||||
|
*/
|
||||||
|
public fun <T: Comparable<T>> Iterator<T>.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 <T: Comparable<T>> Iterator<T>.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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -211,6 +211,32 @@ public inline fun <R, C: MutableCollection<in R>> LongArray.mapTo(result: C, tra
|
|||||||
return result
|
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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -211,6 +211,32 @@ public inline fun <R, C: MutableCollection<in R>> ShortArray.mapTo(result: C, tr
|
|||||||
return result
|
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
|
* Partitions this collection into a pair of collections
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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() {
|
test fun sum() {
|
||||||
expect(0) { intArray().sum() }
|
expect(0) { intArray().sum() }
|
||||||
expect(14) { intArray(2, 3, 9).sum() }
|
expect(14) { intArray(2, 3, 9).sum() }
|
||||||
|
|||||||
@@ -101,6 +101,24 @@ class ArraysTest {
|
|||||||
assertEquals(false, arr[1])
|
assertEquals(false, arr[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test fun min() {
|
||||||
|
expect(null, { array<Int>().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<Int>().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() {
|
test fun sum() {
|
||||||
expect(0) { array<Int>().sum() }
|
expect(0) { array<Int>().sum() }
|
||||||
expect(14) { array(2, 3, 9).sum() }
|
expect(14) { array(2, 3, 9).sum() }
|
||||||
|
|||||||
@@ -414,6 +414,28 @@ class CollectionTest {
|
|||||||
expect(arrayList(2, 3, 1)) { list }
|
expect(arrayList(2, 3, 1)) { list }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test fun min() {
|
||||||
|
expect(null, { listOf<Int>().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<Int>().iterator().min() })
|
||||||
|
expect(2, { listOf(2, 3).iterator().min() })
|
||||||
|
}
|
||||||
|
|
||||||
|
test fun max() {
|
||||||
|
expect(null, { listOf<Int>().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<Int>().iterator().max() })
|
||||||
|
expect(3, { listOf(2, 3).iterator().max() })
|
||||||
|
}
|
||||||
|
|
||||||
test fun sum() {
|
test fun sum() {
|
||||||
expect(0) { ArrayList<Int>().sum() }
|
expect(0) { ArrayList<Int>().sum() }
|
||||||
expect(14) { arrayListOf(2, 3, 9).sum() }
|
expect(14) { arrayListOf(2, 3, 9).sum() }
|
||||||
|
|||||||
@@ -407,6 +407,44 @@ fun commons(): ArrayList<GenericFunction> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<T>")
|
||||||
|
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<T>")
|
||||||
|
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 = \"...\")") {
|
templates add f("appendString(buffer: Appendable, separator: String = \", \", prefix: String =\"\", postfix: String = \"\", limit: Int = -1, truncated: String = \"...\")") {
|
||||||
doc =
|
doc =
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
|
|||||||
var isInline : Boolean = true;
|
var isInline : Boolean = true;
|
||||||
private val customReceivers = HashMap<Family, String>()
|
private val customReceivers = HashMap<Family, String>()
|
||||||
val blockedFor = HashSet<Family>()
|
val blockedFor = HashSet<Family>()
|
||||||
|
private val blockedForPrimitive = HashSet<PrimitiveType>()
|
||||||
val bodies = HashMap<Family, String>()
|
val bodies = HashMap<Family, String>()
|
||||||
val returnTypes = HashMap<Family, String>()
|
val returnTypes = HashMap<Family, String>()
|
||||||
val typeParams = ArrayList<String>()
|
val typeParams = ArrayList<String>()
|
||||||
@@ -57,6 +58,10 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
|
|||||||
blockedFor.addAll(f.toList())
|
blockedFor.addAll(f.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun absentFor(vararg p: PrimitiveType) {
|
||||||
|
blockedForPrimitive.addAll(p.toList())
|
||||||
|
}
|
||||||
|
|
||||||
private fun effectiveTypeParams(f : Family) : List<String> {
|
private fun effectiveTypeParams(f : Family) : List<String> {
|
||||||
val types = ArrayList(typeParams)
|
val types = ArrayList(typeParams)
|
||||||
if (typeParams.find { it.startsWith("T") } == null && !customReceivers.containsKey(f)) {
|
if (typeParams.find { it.startsWith("T") } == null && !customReceivers.containsKey(f)) {
|
||||||
@@ -74,6 +79,7 @@ class GenericFunction(val signature : String): Comparable<GenericFunction> {
|
|||||||
|
|
||||||
fun buildFor(f: Family, primitiveType: PrimitiveType?) : String {
|
fun buildFor(f: Family, primitiveType: PrimitiveType?) : String {
|
||||||
if (blockedFor.contains(f)) return ""
|
if (blockedFor.contains(f)) return ""
|
||||||
|
if (primitiveType != null && blockedForPrimitive.contains(primitiveType)) return ""
|
||||||
|
|
||||||
if (returnTypes[f] == null) throw RuntimeException("No return type specified for $signature")
|
if (returnTypes[f] == null) throw RuntimeException("No return type specified for $signature")
|
||||||
val retType = returnTypes[f]!!
|
val retType = returnTypes[f]!!
|
||||||
|
|||||||
Reference in New Issue
Block a user