Feature: Polynomials and rational functions #469

Merged
lounres merged 132 commits from feature/polynomials into dev 2022-07-28 18:04:06 +03:00
Showing only changes of commit fe4eb96dae - Show all commits

View File

@ -9,7 +9,13 @@ import kotlin.contracts.InvocationKind.*
import kotlin.contracts.contract
// TODO: Docs
/**
* Computes the given lambda [compute] on value corresponding to the provided [key] or `null` if the key is not present.
*
* @param key key which corresponding value will be used if it's present.
* @param compute lambda that is computed on the received value.
* @return result of the computation of the lambda.
*/
internal inline fun <K, V, R> Map<in K, V>.computeOn(key: K, compute: (V?) -> R): R {
contract {
callsInPlace(compute, EXACTLY_ONCE)
@ -17,7 +23,15 @@ internal inline fun <K, V, R> Map<in K, V>.computeOn(key: K, compute: (V?) -> R)
return compute(get(key))
}
// TODO: Docs
/**
* Computes the given lambda [compute] on value corresponding to the provided [key] or computes the given lambda
* [defaultResult] if the key is not present.
*
* @param key key which corresponding value will be used if it's present.
* @param compute lambda that is computed on the value corresponding to the [key].
* @param defaultResult lambda that is computed if the [key] is not present.
* @return result of [compute] lambda if the [key] is present or result of [defaultResult] otherwise.
*/
internal inline fun <K, V, R> Map<K, V>.computeOnOrElse(key: K, defaultResult: () -> R, compute: (value: V) -> R): R {
contract {
callsInPlace(defaultResult, AT_MOST_ONCE)
@ -27,7 +41,15 @@ internal inline fun <K, V, R> Map<K, V>.computeOnOrElse(key: K, defaultResult: (
return (if (key !in this) defaultResult() else compute(get(key) as V))
}
// TODO: Docs
/**
* Computes the given lambda [compute] on value corresponding to the provided [key] or computes the given lambda
* [defaultResult] if the key is not present.
*
* @param key key which corresponding value will be used if it's present.
* @param compute lambda that is computed on the value corresponding to the [key].
* @param defaultResult default result that is returned in case of the [key]'s absence.
* @return result of [compute] lambda if the [key] is present or [defaultResult] otherwise.
*/
internal inline fun <K, V, R> Map<K, V>.computeOnOrElse(key: K, defaultResult: R, compute: (value: V) -> R): R {
contract {
callsInPlace(compute, AT_MOST_ONCE)
@ -35,7 +57,15 @@ internal inline fun <K, V, R> Map<K, V>.computeOnOrElse(key: K, defaultResult: R
return computeOnOrElse(key, { defaultResult }, compute)
}
// TODO: Docs
/**
* Computes the given lambda [compute] on value corresponding to the provided [key] or computes the given lambda
* [defaultResult] if the key is not present.
*
* @param key key which corresponding value will be used if it's present.
* @param compute lambda that is computed on the value corresponding to the [key].
* @param defaultResult default result that is returned in case of the [key]'s absence.
* @return result of [compute] lambda if the [key] is present or [defaultResult] otherwise.
*/
internal inline fun <K, V, R> Map<K, V>.computeOnOrElse(key: K, defaultResult: R, compute: (key: K, value: V) -> R): R {
contract {
callsInPlace(compute, AT_MOST_ONCE)
@ -374,8 +404,20 @@ internal inline fun <K, V, W, D: MutableMap<K, W>> Map<out K, V>.copyMapToBy(des
internal inline fun <K, V, W, D: MutableMap<K, W>> Map<out K, V>.copyMapToBy(destination: D, transform: (key: K, value: V) -> W, resolve: (currentValue: W, newValue: V) -> W): D =
copyMapToBy(destination, { (key, value) -> transform(key, value) }, { _, currentValue, newValue -> resolve(currentValue, newValue) })
// TODO: Docs
internal fun <K, V, D: MutableMap<K, V>> mergeTo(map1: Map<out K, V>, map2: Map<out K, V>, destination: D): D {
/**
* Merges [the first map][map1] and [the second map][map2] prioritising the second one, puts result to the [destination]
* and returns the [destination].
*
* Precisely, corresponding keys and values of the received maps are put into the destination overriding existing values
* in the [destination] if needed. For every key appearing in both maps corresponding value from the second map is
* chosen.
*
* @param map1 the first (less prioritised) map to merge.
* @param map2 the second (more prioritised) map to merge.
* @param destination the map where result of the merge is put.
* @return the destination.
*/
internal fun <K, V, D: MutableMap<in K, in V>> mergeTo(map1: Map<out K, V>, map2: Map<out K, V>, destination: D): D {
for ((key, value) in map1) {
destination.put(key, value)
}
@ -385,7 +427,20 @@ internal fun <K, V, D: MutableMap<K, V>> mergeTo(map1: Map<out K, V>, map2: Map<
return destination
}
// TODO: Docs
/**
* Merges [the first map][map1] and [the second map][map2] resolving conflicts with [resolve] lambda, puts result to the
* [destination] and returns the [destination].
*
* Precisely, corresponding keys and values of the received maps are put into the destination overriding existing values
* in the [destination] if needed. For every key appearing in both maps corresponding value is a result of the [resolve]
* lambda calculated on the key and its corresponding values from the merged maps.
*
* @param map1 the first (less prioritised) map to merge.
* @param map2 the second (more prioritised) map to merge.
* @param resolve lambda function that resolves merge conflicts.
* @param destination the map where result of the merge is put.
* @return the destination.
*/
internal inline fun <K, V1: W, V2: W, W, D: MutableMap<K, W>> mergeToBy(map1: Map<out K, V1>, map2: Map<out K, V2>, destination: D, resolve: (key: K, value1: V1, value2: V2) -> W): D {
for (key in map2.keys) {
destination.remove(key)
@ -400,27 +455,82 @@ internal inline fun <K, V1: W, V2: W, W, D: MutableMap<K, W>> mergeToBy(map1: Ma
return destination
}
// TODO: Docs
/**
* Merges [the first map][map1] and [the second map][map2] resolving conflicts with [resolve] lambda, puts result to the
* [destination] and returns the [destination].
*
* Precisely, corresponding keys and values of the received maps are put into the destination overriding existing values
* in the [destination] if needed. For every key appearing in both maps corresponding value is a result of the [resolve]
* lambda calculated on the key's corresponding values from the merged maps.
*
* @param map1 the first (less prioritised) map to merge.
* @param map2 the second (more prioritised) map to merge.
* @param resolve lambda function that resolves merge conflicts.
* @param destination the map where result of the merge is put.
* @return the destination.
*/
internal inline fun <K, V1: W, V2: W, W, D: MutableMap<K, W>> mergeToBy(map1: Map<K, V1>, map2: Map<K, V2>, destination: D, resolve: (value1: V1, value2: V2) -> W): D =
mergeToBy(map1, map2, destination) { _, value1, value2 -> resolve(value1, value2) }
// TODO: Docs
/**
* Merges [the first map][map1] and [the second map][map2] prioritising the second one.
*
* Precisely, corresponding keys and values of the received maps are put into a new empty map which is returned after
* afterwards. For every key appearing in both maps corresponding value from the second map is chosen.
*
* @param map1 the first (less prioritised) map to merge.
* @param map2 the second (more prioritised) map to merge.
* @return the result of the merge.
*/
internal fun <K, V1: W, V2: W, W> merge(map1: Map<K, V1>, map2: Map<K, V2>): Map<K, W> {
val result = LinkedHashMap<K, W>(map1.size + map2.size)
return mergeTo(map1, map2, result)
}
// TODO: Docs
internal inline fun <K, V1: W, V2: W, W> mergeBy(map1: Map<K, V1>, map2: Map<K, V2>, transform: (key: K, value1: V1, value2: V2) -> W): Map<K, W> {
/**
* Merges [the first map][map1] and [the second map][map2] resolving conflicts with [resolve] lambda.
*
* Precisely, corresponding keys and values of the received maps are put into a new empty map which is returned after
* afterwards. For every key appearing in both maps corresponding value is a result of the [resolve] lambda calculated
* on the key and its corresponding values from the merged maps.
*
* @param map1 the first (less prioritised) map to merge.
* @param map2 the second (more prioritised) map to merge.
* @param resolve lambda function that resolves merge conflicts.
* @return the result of the merge.
*/
internal inline fun <K, V1: W, V2: W, W> mergeBy(map1: Map<K, V1>, map2: Map<K, V2>, resolve: (key: K, value1: V1, value2: V2) -> W): Map<K, W> {
val result = LinkedHashMap<K, W>(map1.size + map2.size)
return mergeToBy(map1, map2, result, transform)
return mergeToBy(map1, map2, result, resolve)
}
// TODO: Docs
internal inline fun <K, V1: W, V2: W, W> mergeBy(map1: Map<K, V1>, map2: Map<K, V2>, transform: (value1: V1, value2: V2) -> W): Map<K, W> =
mergeBy(map1, map2) { _, value1, value2 -> transform(value1, value2) }
/**
* Merges [the first map][map1] and [the second map][map2] resolving conflicts with [resolve] lambda.
*
* Precisely, corresponding keys and values of the received maps are put into a new empty map which is returned after
* afterwards. For every key appearing in both maps corresponding value is a result of the [resolve] lambda calculated
* on the key's corresponding values from the merged maps.
*
* @param map1 the first (less prioritised) map to merge.
* @param map2 the second (more prioritised) map to merge.
* @param resolve lambda function that resolves merge conflicts.
* @return the result of the merge.
*/
internal inline fun <K, V1: W, V2: W, W> mergeBy(map1: Map<K, V1>, map2: Map<K, V2>, resolve: (value1: V1, value2: V2) -> W): Map<K, W> =
mergeBy(map1, map2) { _, value1, value2 -> resolve(value1, value2) }
// TODO: Docs
/**
* Populates the [destination] map with key-value pairs provided by [transform] function applied to each element of the
* given collection resolving conflicts with [resolve] function and returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each element to key-value.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <T, K, V, D : MutableMap<K, V>> Iterable<T>.associateTo(destination: D, transform: (T) -> Pair<K, V>, resolve: (key: K, currentValue: V, newValue: V) -> V): D {
for (element in this) {
val (key, value) = transform(element)
@ -429,7 +539,20 @@ internal inline fun <T, K, V, D : MutableMap<K, V>> Iterable<T>.associateTo(dest
return destination
}
// TODO: Docs
/**
* Populates the [destination] map with key-value pairs, where key is provided by [keySelector] function and value is
* provided by [valueTransform] applied to each element of the given collection, resolving conflicts with [resolve]
* function and returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param valueTransform lambda functions that generates value for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <T, K, V, D : MutableMap<K, V>> Iterable<T>.associateByTo(destination: D, keySelector: (T) -> K, valueTransform: (T) -> V, resolve: (key: K, currentValue: V, newValue: V) -> V): D {
for (element in this) {
val key = keySelector(element)
@ -439,7 +562,19 @@ internal inline fun <T, K, V, D : MutableMap<K, V>> Iterable<T>.associateByTo(de
return destination
}
// TODO: Docs
/**
* Populates the [destination] map with key-value pairs, where key is provided by [keySelector] function applied to each
* element of the given collection and value is the element itself, resolving conflicts with [resolve] function and
* returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <T, K, D : MutableMap<K, T>> Iterable<T>.associateByTo(destination: D, keySelector: (T) -> K, resolve: (key: K, currentValue: T, newValue: T) -> T): D {
for (element in this) {
val key = keySelector(element)
@ -448,86 +583,324 @@ internal inline fun <T, K, D : MutableMap<K, T>> Iterable<T>.associateByTo(desti
return destination
}
// TODO: Docs
/**
* Populates the [destination] map with key-value pairs provided by [transform] function applied to each element of the
* given collection resolving conflicts with [resolve] function and returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each element to key-value pair.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <T, K, V, D : MutableMap<K, V>> Iterable<T>.associateTo(destination: D, transform: (T) -> Pair<K, V>, resolve: (currentValue: V, newValue: V) -> V): D =
associateTo(destination, transform) { _, currentValue, newValue -> resolve(currentValue, newValue) }
// TODO: Docs
/**
* Populates the [destination] map with key-value pairs, where key is provided by [keySelector] function and value is
* provided by [valueTransform] applied to each element of the given collection, resolving conflicts with [resolve]
* function and returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param valueTransform lambda functions that generates value for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <T, K, V, D : MutableMap<K, V>> Iterable<T>.associateByTo(destination: D, keySelector: (T) -> K, valueTransform: (T) -> V, resolve: (currentValue: V, newValue: V) -> V): D =
associateByTo(destination, keySelector, valueTransform) { _, currentValue, newValue -> resolve(currentValue, newValue) }
// TODO: Docs
/**
* Populates the [destination] map with key-value pairs, where key is provided by [keySelector] function applied to each
* element of the given collection and value is the element itself, resolving conflicts with [resolve] function and
* returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <T, K, D : MutableMap<K, T>> Iterable<T>.associateByTo(destination: D, keySelector: (T) -> K, resolve: (currentValue: T, newValue: T) -> T): D =
associateByTo(destination, keySelector) { _, currentValue, newValue -> resolve(currentValue, newValue) }
// TODO: Docs
/**
* Returns a map containing key-value pairs provided by [transform] function applied to elements of the given collection.
*
* All pairs are added in order of iteration. If some key is already added to the map, adding new key-value pair with the
* key is resolved with [resolve] function which takes the key, current value corresponding to the key, and new value
* from the pair.
*
* @param transform function which transforms each element to key-value pair.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>, resolve: (key: K, currentValue: V, newValue: V) -> V): Map<K, V> =
associateTo(LinkedHashMap(), transform, resolve)
// TODO: Docs
/**
* Returns a map containing the values provided by [valueTransform] and indexed by [keySelector] functions applied to
* elements of the given collection.
*
* All pairs are added in order of iteration. If some key is already added to the map, adding new key-value pair with
* the key is resolved with [resolve] function which takes the key, current value corresponding to the key, and new
* value from the pair.
*
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param valueTransform lambda functions that generates value for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V, resolve: (key: K, currentValue: V, newValue: V) -> V): Map<K, V> =
associateByTo(LinkedHashMap(), keySelector, valueTransform, resolve)
// TODO: Docs
/**
* Returns a map containing the elements from the given collection indexed by the key returned from [keySelector]
* function applied to each element.
*
* All pairs are added in order of iteration. If some key is already added to the map, adding new key-value pair with
* the key is resolved with [resolve] function which takes the key, current value corresponding to the key, and new
* value from the pair.
*
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <T, K> Iterable<T>.associateBy(keySelector: (T) -> K, resolve: (key: K, currentValue: T, newValue: T) -> T): Map<K, T> =
associateByTo(LinkedHashMap(), keySelector, resolve)
// TODO: Docs
/**
* Returns a map containing key-value pairs provided by [transform] function applied to elements of the given collection.
*
* All pairs are added in order of iteration. If some key is already added to the map, adding new key-value pair with
* the key is resolved with [resolve] function which takes current value corresponding to the key and new value from the
* pair.
*
* @param transform function which transforms each element to key-value pair.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>, resolve: (currentValue: V, newValue: V) -> V): Map<K, V> =
associateTo(LinkedHashMap(), transform, resolve)
// TODO: Docs
/**
* Returns a map containing the values provided by [valueTransform] and indexed by [keySelector] functions applied to
* elements of the given collection.
*
* All pairs are added in order of iteration. If some key is already added to the map, adding new key-value pair with
* the key is resolved with [resolve] function which takes current value corresponding to the key and new value from the
* pair.
*
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param valueTransform lambda functions that generates value for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V, resolve: (currentValue: V, newValue: V) -> V): Map<K, V> =
associateByTo(LinkedHashMap(), keySelector, valueTransform, resolve)
// TODO: Docs
/**
* Returns a map containing the elements from the given collection indexed by the key returned from [keySelector]
* function applied to each element.
*
* All pairs are added in order of iteration. If some key is already added to the map, adding new key-value pair with
* the key is resolved with [resolve] function which takes current value corresponding to the key and new value from the
* pair.
*
* @param keySelector lambda functions that generates keys for the key-value pairs.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <T, K> Iterable<T>.associateBy(keySelector: (T) -> K, resolve: (currentValue: T, newValue: T) -> T): Map<K, T> =
associateByTo(LinkedHashMap(), keySelector, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys of this map and the values obtained
* by applying the [transform] function to each entry in this map resolving conflicts with [resolve] function and
* returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new value.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <K, V, W, D : MutableMap<K, W>> Map<out K, V>.mapValuesTo(destination: D, transform: (Map.Entry<K, V>) -> W, resolve: (key: K, currentValue: W, newValue: W) -> W): D =
entries.associateByTo(destination, { it.key }, transform, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys of this map and the values obtained
* by applying the [transform] function to each entry in this map resolving conflicts with [resolve] function and
* returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new value.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <K, V, W, D : MutableMap<K, W>> Map<out K, V>.mapValuesTo(destination: D, transform: (key: K, value: V) -> W, resolve: (key: K, currentValue: W, newValue: W) -> W): D =
entries.associateByTo(destination, { it.key }, { (key, value) -> transform(key, value) }, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys of this map and the values obtained
* by applying the [transform] function to each entry in this map resolving conflicts with [resolve] function and
* returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new value.
* @param resolve lambda function that resolves merge conflicts which current and new values corresponding to some key.
* @return the [destination].
*/
internal inline fun <K, V, W, D : MutableMap<K, W>> Map<out K, V>.mapValuesTo(destination: D, transform: (Map.Entry<K, V>) -> W, resolve: (currentValue: W, newValue: W) -> W): D =
entries.associateByTo(destination, { it.key }, transform, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys of this map and the values obtained
* by applying the [transform] function to each entry in this map resolving conflicts with [resolve] function and
* returns the [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new value.
* @param resolve lambda function that resolves merge conflicts which current and new values corresponding to some key.
* @return the [destination].
*/
internal inline fun <K, V, W, D : MutableMap<K, W>> Map<out K, V>.mapValuesTo(destination: D, transform: (key: K, value: V) -> W, resolve: (currentValue: W, newValue: W) -> W): D =
entries.associateByTo(destination, { it.key }, { (key, value) -> transform(key, value) }, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys obtained by applying the [transform] function to
* each entry in this map and the values of this map, resolving conflicts with [resolve] function and returns the
* [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <K, V, L, D : MutableMap<L, V>> Map<out K, V>.mapKeysTo(destination: D, transform: (Map.Entry<K, V>) -> L, resolve: (key: L, currentValue: V, newValue: V) -> V): D =
entries.associateByTo(destination, transform, { it.value }, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys obtained by applying the [transform] function to
* each entry in this map and the values of this map, resolving conflicts with [resolve] function and returns the
* [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the [destination].
*/
internal inline fun <K, V, L, D : MutableMap<L, V>> Map<out K, V>.mapKeysTo(destination: D, transform: (key: K, value: V) -> L, resolve: (key: L, currentValue: V, newValue: V) -> V): D =
entries.associateByTo(destination, { (key, value) -> transform(key, value) }, { it.value }, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys obtained by applying the [transform] function to
* each entry in this map and the values of this map, resolving conflicts with [resolve] function and returns the
* [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which current and new values corresponding to some key.
* @return the [destination].
*/
internal inline fun <K, V, L, D : MutableMap<L, V>> Map<out K, V>.mapKeysTo(destination: D, transform: (Map.Entry<K, V>) -> L, resolve: (currentValue: V, newValue: V) -> V): D =
entries.associateByTo(destination, transform, { it.value }, resolve)
// TODO: Docs
/**
* Populates the given [destination] map with entries having the keys obtained by applying the [transform] function to
* each entry in this map and the values of this map, resolving conflicts with [resolve] function and returns the
* [destination].
*
* All pairs are added and resolved in order of iteration.
*
* @param destination the destination of the generated key-value pairs.
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which current and new values corresponding to some key.
* @return the [destination].
*/
internal inline fun <K, V, L, D : MutableMap<L, V>> Map<out K, V>.mapKeysTo(destination: D, transform: (key: K, value: V) -> L, resolve: (currentValue: V, newValue: V) -> V): D =
entries.associateByTo(destination, { (key, value) -> transform(key, value) }, { it.value }, resolve)
// TODO: Docs
/**
* Returns a new map with entries having the keys obtained by applying the [transform] function to each entry in this
* map and the values of this map and resolving conflicts with [resolve] function.
*
* All pairs are added and resolved in order of iteration.
*
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <K, V, L> Map<out K, V>.mapKeys(transform: (Map.Entry<K, V>) -> L, resolve: (key: L, currentValue: V, newValue: V) -> V): Map<L, V> =
mapKeysTo(LinkedHashMap(size), transform, resolve)
// TODO: Docs
/**
* Returns a new map with entries having the keys obtained by applying the [transform] function to each entry in this
* map and the values of this map and resolving conflicts with [resolve] function.
*
* All pairs are added and resolved in order of iteration.
*
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which receives some key, its current, and new
* corresponding values.
* @return the result map.
*/
internal inline fun <K, V, L> Map<out K, V>.mapKeys(transform: (key: K, value: V) -> L, resolve: (key: L, currentValue: V, newValue: V) -> V): Map<L, V> =
mapKeysTo(LinkedHashMap(size), transform, resolve)
// TODO: Docs
/**
* Returns a new map with entries having the keys obtained by applying the [transform] function to each entry in this
* map and the values of this map and resolving conflicts with [resolve] function.
*
* All pairs are added and resolved in order of iteration.
*
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which current and new values corresponding to some key.
* @return the result map.
*/
internal inline fun <K, V, L> Map<out K, V>.mapKeys(transform: (Map.Entry<K, V>) -> L, resolve: (currentValue: V, newValue: V) -> V): Map<L, V> =
mapKeysTo(LinkedHashMap(size), transform, resolve)
// TODO: Docs
/**
* Returns a new map with entries having the keys obtained by applying the [transform] function to each entry in this
* map and the values of this map and resolving conflicts with [resolve] function..
*
* All pairs are added and resolved in order of iteration.
*
* @param transform function which transforms each key-value pair to new key.
* @param resolve lambda function that resolves merge conflicts which current and new values corresponding to some key.
* @return the result map.
*/
internal inline fun <K, V, L> Map<out K, V>.mapKeys(transform: (key: K, value: V) -> L, resolve: (currentValue: V, newValue: V) -> V): Map<L, V> =
mapKeysTo(LinkedHashMap(size), transform, resolve)