commonMain.com.bkahlert.kommons.collections.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kommons-core-jvm Show documentation
Show all versions of kommons-core-jvm Show documentation
Kommons Core is a Kotlin Multiplatform Library that offers shared features for all Kommons modules.
package com.bkahlert.kommons
/** Throws an [IllegalArgumentException] if the specified [collection] [isEmpty]. */
@Suppress("NOTHING_TO_INLINE")
public inline fun > requireNotEmpty(collection: T): T = collection.also { require(it.isNotEmpty()) }
/** Throws an [IllegalArgumentException] if the specified [array] [isEmpty]. */
@Suppress("NOTHING_TO_INLINE")
public inline fun requireNotEmpty(array: Array): Array = array.also { require(it.isNotEmpty()) }
/** Throws an [IllegalArgumentException] with the result of calling [lazyMessage] if the specified [collection] [isEmpty]. */
public inline fun > requireNotEmpty(collection: T, lazyMessage: () -> Any): T = collection.also { require(it.isNotEmpty(), lazyMessage) }
/** Throws an [IllegalArgumentException] with the result of calling [lazyMessage] if the specified [array] [isEmpty]. */
public inline fun requireNotEmpty(array: Array, lazyMessage: () -> Any): Array = array.also { require(it.isNotEmpty(), lazyMessage) }
/** Throws an [IllegalStateException] if the specified [collection] [isEmpty]. */
@Suppress("NOTHING_TO_INLINE")
public inline fun > checkNotEmpty(collection: T): T = collection.also { check(it.isNotEmpty()) }
/** Throws an [IllegalStateException] if the specified [array] [isEmpty]. */
@Suppress("NOTHING_TO_INLINE")
public inline fun checkNotEmpty(array: Array): Array = array.also { check(it.isNotEmpty()) }
/** Throws an [IllegalStateException] with the result of calling [lazyMessage] if the specified [collection] [isEmpty]. */
public inline fun > checkNotEmpty(collection: T, lazyMessage: () -> Any): T = collection.also { check(it.isNotEmpty(), lazyMessage) }
/** Throws an [IllegalStateException] with the result of calling [lazyMessage] if the specified [array] [isEmpty]. */
public inline fun checkNotEmpty(array: Array, lazyMessage: () -> Any): Array = array.also { check(it.isNotEmpty(), lazyMessage) }
/** Returns this collection if it [isNotEmpty] or `null`, if it is. */
@Suppress("NOTHING_TO_INLINE")
public inline fun > T.takeIfNotEmpty(): T? = takeIf { it.isNotEmpty() }
/** Returns this array if it [isNotEmpty] or `null`, if it is. */
@Suppress("NOTHING_TO_INLINE")
public inline fun Array.takeIfNotEmpty(): Array? = takeIf { it.isNotEmpty() }
/** Returns this collection if it [isNotEmpty] or `null`, if it is. */
@Suppress("NOTHING_TO_INLINE")
public inline fun > T.takeUnlessEmpty(): T? = takeUnless { it.isEmpty() }
/** Returns this array if it [isNotEmpty] or `null`, if it is. */
@Suppress("NOTHING_TO_INLINE")
public inline fun Array.takeUnlessEmpty(): Array? = takeUnless { it.isEmpty() }
/** The first element of this collection. Throws a [NoSuchElementException] if this collection is empty. */
public inline val Iterable.head: T get() = first()
/** The first element of this collection or `null` if this collection is empty. */
public inline val Iterable.headOrNull: T? get() = firstOrNull()
/** A list containing all but the first element of this collection. */
public inline val Iterable.tail: List get() = drop(1)
/**
* Returns an index pair with:
* - [Pair.first] being the index of the located element, and
* - [Pair.second] being the virtual index inside the located element.
*
* The length of each element is computed with the specified [length].
*
* @throws IndexOutOfBoundsException if the specified [index] doesn't locate an element
*/
public fun Iterable.locate(index: Int, length: (T) -> Int): Pair {
if (index < 0) throw IndexOutOfBoundsException("index out of range: $index")
var virtualIndex = index
for ((actualIndex, element) in withIndex()) {
val elementLength = length(element)
if (virtualIndex < elementLength) return actualIndex to virtualIndex
else virtualIndex -= elementLength
}
throw IndexOutOfBoundsException("index out of range: $index")
}
/**
* Returns a triple with:
* - [Triple.first] being the indices of the located elements,
* - [Triple.second] being the virtual index inside the first located element, and
* - [Triple.third] being the virtual exclusive index inside the second located element.
*
* The length of each element is computed with the specified [length].
*
* @throws IndexOutOfBoundsException if the specified [startIndex] or [endIndex] doesn't locate an element
*/
public fun Iterable.locate(startIndex: Int, endIndex: Int, length: (T) -> Int): Triple {
if (endIndex <= startIndex) throw IndexOutOfBoundsException("begin $startIndex, end $endIndex")
val (elementStartIndex, virtualStartIndex) = locate(startIndex, length)
val (elementEndIndex, virtualEndIndex) = locate(endIndex - 1, length)
return (elementStartIndex..elementEndIndex) to virtualStartIndex too virtualEndIndex + 1
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy