All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fuookami.ospf.kotlin.utils.functional.Collection.kt Maven / Gradle / Ivy

There is a newer version: 1.0.29
Show newest version
package fuookami.ospf.kotlin.utils.functional

import java.util.*
import kotlin.*
import kotlin.collections.*
import kotlin.reflect.full.*
import fuookami.ospf.kotlin.utils.math.*
import fuookami.ospf.kotlin.utils.math.ordinary.*
import fuookami.ospf.kotlin.utils.operator.*
import kotlin.random.Random

fun  List.shuffle(
    randomGenerator: Generator = { Random.nextInt(0, this.size) }
): List {
    val list = this.toMutableList()
    for (i in list.size - 1 downTo 1) {
        val j = randomGenerator()!! % list.size
        val temp = list[i]
        list[i] = list[j]
        list[j] = temp
    }
    return list
}

fun  Iterator.collect(): List {
    return this.collectTo(ArrayList())
}

fun > Iterator.collectTo(m: M): M {
    while (this.hasNext()) {
        m.add(this.next())
    }
    return m
}

inline fun  Iterable.lastNotNullOf(
    crossinline extractor: Extractor
): R {
    var result: R? = null

    val iterator = this.iterator()
    while (iterator.hasNext()) {
        result = extractor(iterator.next())
    }

    return result ?: throw NoSuchElementException("No element of the collection was transformed to a non-null value.")
}

inline fun  List.lastNotNullOf(
    crossinline extractor: Extractor
): R {
    val iterator = this.listIterator()
    while (iterator.hasPrevious()) {
        val result = extractor(iterator.next())

        if (result != null) {
            return result
        }
    }

    throw NoSuchElementException("No element of the collection was transformed to a non-null value.")
}

inline fun  Iterable.lastNotNullOfOrNull(
    crossinline extractor: Extractor
): R? {
    var result: R? = null

    val iterator = this.iterator()
    while (iterator.hasNext()) {
        result = extractor(iterator.next())
    }

    return result
}

inline fun  List.lastNotNullOfOrNull(
    crossinline extractor: Extractor
): R? {
    val iterator = this.listIterator()
    while (iterator.hasPrevious()) {
        val result = extractor(iterator.next())

        if (result != null) {
            return result
        }
    }

    return null
}

inline fun  Iterable.filterNotNull(
    crossinline predicate: Predicate
): List {
    return this.filterNotNullTo(ArrayList(), predicate)
}

inline fun > Iterable.filterNotNullTo(
    destination: C,
    crossinline predicate: Predicate
): C {
    for (element in this.iterator()) {
        if (element != null && predicate(element)) {
            destination.add(element)
        }
    }
    return destination
}

inline fun  Iterable.filterIsInstance(
    crossinline predicate: Predicate
): List {
    return this.filterIsInstanceTo(ArrayList(), predicate)
}

inline fun > Iterable.filterIsInstanceTo(
    destination: C,
    crossinline predicate: Predicate
): C {
    for (element in this.iterator()) {
        if (element is U && predicate(element)) {
            destination.add(element)
        }
    }
    return destination
}

inline fun  Iterable.flatMapNotNull(
    crossinline extractor: Extractor, T>
): List {
    return this.flatMapNotNullTo(ArrayList(), extractor)
}

inline fun > Iterable.flatMapNotNullTo(
    destination: C,
    crossinline extractor: Extractor, T>
): C {
    for (element in this.iterator()) {
        destination.addAll(extractor(element).filterNotNull())
    }
    return destination
}

inline fun  Iterable.maxWithComparator(
    crossinline comparator: Comparator
): T {
    return this.maxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.maxWithPartialComparator(
    crossinline comparator: PartialComparator
): T {
    return this.maxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.maxWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
): T {
    return this.maxOfWith({ lhs, rhs ->
        comparator(lhs, rhs).value
    }) { it }
}

inline fun  Iterable.maxWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
): T {
    return this.maxOfWith({ lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }) { it }
}

inline fun  Iterable.maxWithComparatorOrNull(
    crossinline comparator: Comparator
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.maxWithPartialComparatorOrNull(
    crossinline comparator: PartialComparator
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.maxWithThreeWayComparatorOrNull(
    crossinline comparator: ThreeWayComparator
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs).value
    }) { it }
}

inline fun  Iterable.maxWithPartialThreeWayComparatorOrNull(
    crossinline comparator: PartialThreeWayComparator
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs)?.value ?: 0
    }) { it }
}

inline fun  Iterable.maxOfWithComparator(
    crossinline comparator: Comparator,
    crossinline extractor: Extractor
): T {
    return this.maxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.maxOfWithPartialComparator(
    crossinline comparator: PartialComparator,
    crossinline extractor: Extractor
): T {
    return this.maxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.maxOfWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator,
    crossinline extractor: Extractor
): T {
    return this.maxOfWith({ lhs, rhs ->
        comparator(lhs, rhs).value
    }, extractor)
}

inline fun  Iterable.maxOfWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator,
    crossinline extractor: Extractor
): T {
    return this.maxOfWith({ lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }, extractor)
}

inline fun  Iterable.maxOfWithComparatorOrNull(
    crossinline comparator: Comparator,
    crossinline extractor: Extractor
): T? {
    return this.maxOfWithOrNull({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.maxOfWithPartialComparatorOrNull(
    crossinline comparator: PartialComparator,
    crossinline extractor: Extractor
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.maxOfWithThreeWayComparatorOrNull(
    crossinline comparator: ThreeWayComparator,
    crossinline extractor: Extractor
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs).value
    }, extractor)
}

inline fun  Iterable.maxOfWithPartialThreeWayComparatorOrNull(
    crossinline comparator: PartialThreeWayComparator,
    crossinline extractor: Extractor
): T? {
    return this.maxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs)?.value ?: 0
    }, extractor)
}

inline fun  Iterable.minWithComparator(
    crossinline comparator: Comparator
): T {
    return this.minOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minWithPartialComparator(
    crossinline comparator: PartialComparator
): T {
    return this.minOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
): T {
    return this.minOfWith({ lhs, rhs ->
        comparator(lhs, rhs).value
    }) { it }
}

inline fun  Iterable.minWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
): T {
    return this.minOfWith({ lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }) { it }
}

inline fun  Iterable.minWithComparatorOrNull(
    crossinline comparator: Comparator
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minWithPartialComparatorOrNull(
    crossinline comparator: PartialComparator
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minWithThreeWayComparatorOrNull(
    crossinline comparator: ThreeWayComparator
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs).value
    }) { it }
}

inline fun  Iterable.minWithPartialThreeWayComparatorOrNull(
    crossinline comparator: PartialThreeWayComparator
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs)?.value ?: 0
    }) { it }
}

inline fun  Iterable.minOfWithComparator(
    crossinline comparator: Comparator,
    crossinline extractor: Extractor
): T {
    return this.minOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minOfWithPartialComparator(
    crossinline comparator: PartialComparator,
    crossinline extractor: Extractor
): T {
    return this.minOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minOfWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator,
    crossinline extractor: Extractor
): T {
    return this.minOfWith({ lhs, rhs ->
        comparator(lhs, rhs).value
    }, extractor)
}

inline fun  Iterable.minOfWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator,
    crossinline extractor: Extractor
): T {
    return this.minOfWith({ lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }, extractor)
}

inline fun  Iterable.minOfWithComparatorOrNull(
    crossinline comparator: Comparator,
    crossinline extractor: Extractor
): T? {
    return this.minOfWithOrNull({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minOfWithPartialComparatorOrNull(
    crossinline comparator: PartialComparator,
    crossinline extractor: Extractor
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minOfWithThreeWayComparatorOrNull(
    crossinline comparator: ThreeWayComparator,
    crossinline extractor: Extractor
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs).value
    }, extractor)
}

inline fun  Iterable.minOfWithPartialThreeWayComparatorOrNull(
    crossinline comparator: PartialThreeWayComparator,
    crossinline extractor: Extractor
): T? {
    return this.minOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs)?.value ?: 0
    }, extractor)
}


fun > Iterable.minMax(): Pair {
    val iterator = this.iterator()
    if (!iterator.hasNext()) {
        throw NoSuchElementException()
    }

    var min = iterator.next()
    var max = min
    while (iterator.hasNext()) {
        val v = iterator.next()
        if (v < min) {
            min = v
        }
        if (v > max) {
            max = v
        }
    }
    return Pair(min, max)
}

fun > Iterable.minMaxOrNull(): Pair? {
    val iterator = this.iterator()
    if (!iterator.hasNext()) {
        return null
    }

    var min = iterator.next()
    var max = min
    while (iterator.hasNext()) {
        val v = iterator.next()
        if (v < min) {
            min = v
        }
        if (v > max) {
            max = v
        }
    }
    return Pair(min, max)
}

inline fun > Iterable.minMaxBy(
    crossinline extractor: Extractor
): Pair {
    val iterator = this.iterator()
    if (!iterator.hasNext()) {
        throw NoSuchElementException()
    }

    val v = iterator.next()
    val r = extractor(v)
    var min = Pair(v, r)
    var max = Pair(v, r)
    while (iterator.hasNext()) {
        val v0 = iterator.next()
        val r0 = extractor(v0)
        if (r0 < min.second) {
            min = Pair(v0, r0)
        }
        if (r0 > max.second) {
            max = Pair(v0, r0)
        }
    }
    return Pair(min.first, max.first)
}

inline fun > Iterable.minMaxByOrNull(
    crossinline extractor: Extractor
): Pair? {
    val iterator = this.iterator()
    if (!iterator.hasNext()) {
        return null
    }

    val v = iterator.next()
    val r = extractor(v)
    var min = Pair(v, r)
    var max = Pair(v, r)
    while (iterator.hasNext()) {
        val v0 = iterator.next()
        val r0 = extractor(v0)
        if (r0 < min.second) {
            min = Pair(v0, r0)
        }
        if (r0 > max.second) {
            max = Pair(v0, r0)
        }
    }
    return Pair(min.first, max.first)
}

inline fun > Iterable.minMaxOf(
    crossinline extractor: Extractor
): Pair {
    val iterator = this.iterator()
    if (!iterator.hasNext()) {
        throw NoSuchElementException()
    }

    var min = extractor(iterator.next())
    var max = min
    while (iterator.hasNext()) {
        val v = extractor(iterator.next())
        if (v < min) {
            min = v
        }
        if (v > max) {
            max = v
        }
    }
    return Pair(min, max)
}

inline fun > Iterable.minMaxOfOrNull(
    crossinline extractor: Extractor
): Pair? {
    val iterator = this.iterator()
    if (!iterator.hasNext()) {
        return null
    }

    var min = extractor(iterator.next())
    var max = min
    while (iterator.hasNext()) {
        val v = extractor(iterator.next())
        if (v < min) {
            min = v
        }
        if (v > max) {
            max = v
        }
    }
    return Pair(min, max)
}

inline fun  Iterable.minMaxWithComparator(
    crossinline comparator: Comparator
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minMaxWithPartialComparator(
    crossinline comparator: PartialComparator
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minMaxWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        comparator(lhs, rhs).value
    }) { it }
}

inline fun  Iterable.minMaxWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }) { it }
}

inline fun  Iterable.minMaxWithComparatorOrNull(
    crossinline comparator: Comparator
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minMaxWithPartialComparatorOrNull(
    crossinline comparator: PartialComparator
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }) { it }
}

inline fun  Iterable.minMaxWithThreeWayComparatorOrNull(
    crossinline comparator: ThreeWayComparator
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs).value
    }) { it }
}

inline fun  Iterable.minMaxWithPartialThreeWayComparatorOrNull(
    crossinline comparator: PartialThreeWayComparator
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs)?.value ?: 0
    }) { it }
}

inline fun  Iterable.minMaxOfWithComparator(
    crossinline comparator: Comparator,
    crossinline extractor: Extractor
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minMaxOfWithPartialComparator(
    crossinline comparator: PartialComparator,
    crossinline extractor: Extractor
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minMaxOfWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator,
    crossinline extractor: Extractor
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        comparator(lhs, rhs).value
    }, extractor)
}

inline fun  Iterable.minMaxOfWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator,
    crossinline extractor: Extractor
): Pair {
    return this.minMaxOfWith({ lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }, extractor)
}

inline fun  Iterable.minMaxOfWithComparatorOrNull(
    crossinline comparator: Comparator,
    crossinline extractor: Extractor
): Pair? {
    return this.minMaxOfWithOrNull({ lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minMaxOfWithPartialComparatorOrNull(
    crossinline comparator: PartialComparator,
    crossinline extractor: Extractor
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }, extractor)
}

inline fun  Iterable.minMaxOfWithThreeWayComparatorOrNull(
    crossinline comparator: ThreeWayComparator,
    crossinline extractor: Extractor
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs).value
    }, extractor)
}

inline fun  Iterable.minMaxOfWithPartialThreeWayComparatorOrNull(
    crossinline comparator: PartialThreeWayComparator,
    crossinline extractor: Extractor
): Pair? {
    return this.minMaxOfWithOrNull({ lhs: T, rhs: T ->
        comparator(lhs, rhs)?.value ?: 0
    }, extractor)
}

inline fun  Iterable.associateNotNull(
    crossinline extractor: Extractor?, T>
): Map {
    return this.associateNotNullTo(LinkedHashMap(), extractor)
}

inline fun > Iterable.associateNotNullTo(
    destination: M,
    crossinline extractor: Extractor?, T>
): M {
    return this.mapNotNull(extractor).toMap(destination)
}

inline fun  Iterable.associateByNotNull(
    crossinline extractor: Extractor
): Map {
    return this.associateByNotNullTo(LinkedHashMap(), extractor)
}

inline fun > Iterable.associateByNotNullTo(
    destination: M,
    crossinline extractor: Extractor
): M {
    return this.mapNotNull { extractor(it)?.to(it) }.toMap(destination)
}

inline fun  Iterable.associateWithNotNull(
    crossinline extractor: Extractor
): Map {
    return this.associateWithNotNullTo(LinkedHashMap(), extractor)
}

inline fun > Iterable.associateWithNotNullTo(
    destination: M,
    crossinline extractor: Extractor
): M {
    return this.mapNotNull { extractor(it)?.let { value -> it to value } }.toMap(destination)
}

inline fun  MutableList.sortWithComparator(
    crossinline comparator: Comparator
) {
    this.sortWith { lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }
}

inline fun  MutableList.sortWithPartialComparator(
    crossinline comparator: PartialComparator
) {
    this.sortWith { lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }
}

inline fun  MutableList.sortWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
) {
    this.sortWith { lhs, rhs ->
        comparator(lhs, rhs).value
    }
}

inline fun  MutableList.sortWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
) {
    this.sortWith { lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }
}

inline fun  Iterable.sortedWithComparator(
    crossinline comparator: Comparator
): List {
    return this.sortedWith { lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }
}

inline fun  Iterable.sortedWithPartialComparator(
    crossinline comparator: PartialComparator
): List {
    return this.sortedWith { lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }
}

inline fun  Iterable.sortedWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
): List {
    return this.sortedWith { lhs, rhs ->
        comparator(lhs, rhs).value
    }
}

inline fun  Iterable.sortedWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
): List {
    return this.sortedWith { lhs, rhs ->
        comparator(lhs, rhs)?.value ?: 0
    }
}

inline fun  Iterable.toSortedSetWithComparator(
    crossinline comparator: Comparator
): SortedSet {
    return this.toSortedSet { lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }
}

inline fun  Iterable.toSortedSetWithPartialComparator(
    crossinline comparator: PartialComparator
): SortedSet {
    return this.toSortedSet { lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }
}

inline fun  Iterable.toSortedSetWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
): SortedSet {
    return this.toSortedSet { lhs, rhs -> comparator(lhs, rhs).value }
}

inline fun  Iterable.toSortedSetWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
): SortedSet {
    return this.toSortedSet { lhs, rhs -> comparator(lhs, rhs)?.value ?: 0 }
}

inline fun  Map.toSortedMapWithComparator(
    crossinline comparator: Comparator
): SortedMap {
    return this.toSortedMap { lhs, rhs ->
        if (comparator(lhs, rhs)) {
            -1
        } else if (comparator(rhs, lhs)) {
            1
        } else {
            0
        }
    }
}

inline fun  Map.toSortedMapWithPartialComparator(
    crossinline comparator: PartialComparator
): SortedMap {
    return this.toSortedMap { lhs, rhs ->
        if (comparator(lhs, rhs) == true) {
            -1
        } else if (comparator(rhs, lhs) == true) {
            1
        } else {
            0
        }
    }
}

inline fun  Map.toSortedMapWithThreeWayComparator(
    crossinline comparator: ThreeWayComparator
): SortedMap {
    return this.toSortedMap { lhs, rhs -> comparator(lhs, rhs).value }
}

inline fun  Map.toSortedMapWithPartialThreeWayComparator(
    crossinline comparator: PartialThreeWayComparator
): SortedMap {
    return this.toSortedMap { lhs, rhs -> comparator(lhs, rhs)?.value ?: 0 }
}

@Suppress("UNCHECKED_CAST")
inline fun  Iterable.sum(): T where T : Arithmetic, T : Plus {
    var sum = (T::class.companionObjectInstance!! as ArithmeticConstants).zero
    for (element in this) {
        sum += element
    }
    return sum
}

@Suppress("UNCHECKED_CAST")
inline fun  Iterable.sumOf(
    crossinline extractor: Extractor
): U where U : Arithmetic, U : Plus {
    var sum = (U::class.companionObjectInstance!! as ArithmeticConstants).zero
    for (element in this) {
        sum += extractor(element)
    }
    return sum
}

@Suppress("UNCHECKED_CAST")
inline fun  Map.sum(): V where V : Arithmetic, V : Plus {
    var sum = (V::class.companionObjectInstance!! as ArithmeticConstants).zero
    for (element in this) {
        sum += element.value
    }
    return sum
}

@Suppress("UNCHECKED_CAST")
inline fun  Map.sumOf(
    crossinline extractor: Extractor>
): T where T : Arithmetic, T : Plus {
    var sum = (T::class.companionObjectInstance!! as ArithmeticConstants).zero
    for (element in this) {
        sum += extractor(element)
    }
    return sum
}

@Suppress("UNCHECKED_CAST")
inline fun  Sequence.sum(): T where T : Arithmetic, T : Plus {
    var sum = (T::class.companionObjectInstance!! as ArithmeticConstants).zero
    for (element in this) {
        sum += element
    }
    return sum
}

@Suppress("UNCHECKED_CAST")
inline fun  Sequence.sumOf(
    crossinline extractor: Extractor
): U where U : Arithmetic, U : Plus {
    var sum = (U::class.companionObjectInstance!! as ArithmeticConstants).zero
    for (element in this) {
        sum += extractor(element)
    }
    return sum
}