diff --git a/runtime/src/main/kotlin/kotlin/Arrays.kt b/runtime/src/main/kotlin/kotlin/Arrays.kt index 9ebbe87c68e..04043ac6b6c 100644 --- a/runtime/src/main/kotlin/kotlin/Arrays.kt +++ b/runtime/src/main/kotlin/kotlin/Arrays.kt @@ -1876,4 +1876,305 @@ public inline fun byteArrayOf(vararg elements: Byte) = elements /** * Returns an array containing the specified boolean values. */ -public inline fun booleanArrayOf(vararg elements: Boolean) = elements \ No newline at end of file +public inline fun booleanArrayOf(vararg elements: Boolean) = elements + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun Array.joinTo( + buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", + limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + buffer.appendElement(element, transform) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun ByteArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Byte) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun ShortArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Short) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun IntArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Int) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun LongArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Long) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun FloatArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Float) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun DoubleArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Double) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun BooleanArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", + postfix: CharSequence = "", limit: Int = -1, + truncated: CharSequence = "...", + transform: ((Boolean) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element.toString()) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Appends the string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun CharArray.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", + limit: Int = -1, truncated: CharSequence = "...", transform: ((Char) -> CharSequence)? = null): A { + buffer.append(prefix) + var count = 0 + for (element in this) { + if (++count > 1) buffer.append(separator) + if (limit < 0 || count <= limit) { + if (transform != null) + buffer.append(transform(element)) + else + buffer.append(element) + } else break + } + if (limit >= 0 && count > limit) buffer.append(truncated) + buffer.append(postfix) + return buffer +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun Array.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun ByteArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Byte) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun ShortArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Short) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun IntArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Int) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun LongArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Long) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun FloatArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Float) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun DoubleArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Double) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun BooleanArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Boolean) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + +/** + * Creates a string from all the elements separated using [separator] and using the given [prefix] and [postfix] if supplied. + * + * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] + * elements will be appended, followed by the [truncated] string (which defaults to "..."). + */ +public fun CharArray.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((Char) -> CharSequence)? = null): String { + return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() +} + diff --git a/runtime/src/main/kotlin/kotlin/text/Appendable.kt b/runtime/src/main/kotlin/kotlin/text/Appendable.kt index 3addc63d33f..94250bad486 100644 --- a/runtime/src/main/kotlin/kotlin/text/Appendable.kt +++ b/runtime/src/main/kotlin/kotlin/text/Appendable.kt @@ -5,3 +5,39 @@ interface Appendable { fun append(csq: CharSequence?): Appendable fun append(csq: CharSequence?, start: Int, end: Int): Appendable } + +/** + * Appends all arguments to the given [Appendable]. + */ +public fun T.append(vararg value: CharSequence?): T { + for (item in value) + append(item) + return this +} + +/** + * Appends all arguments to the given StringBuilder. + */ +public fun StringBuilder.append(vararg value: String?): StringBuilder { + for (item in value) + append(item) + return this +} + +/** + * Appends all arguments to the given StringBuilder. + */ +public fun StringBuilder.append(vararg value: Any?): StringBuilder { + for (item in value) + append(item) + return this +} + +internal fun Appendable.appendElement(element: T, transform: ((T) -> CharSequence)?) { + when { + transform != null -> append(transform(element)) + element is CharSequence? -> append(element) + element is Char -> append(element) + else -> append(element.toString()) + } +}