Commonize CharCategory and related functions #KT-39177 #KT-43216 #KT-39906 #KT-30652

This commit is contained in:
Abduqodiri Qurbonzoda
2020-10-13 02:39:07 +03:00
parent 9b429fb535
commit 46b7a774b5
40 changed files with 3573 additions and 62 deletions
+87
View File
@@ -1,6 +1,8 @@
@kotlin.SinceKotlin(version = "1.2")
public val kotlin.String.Companion.CASE_INSENSITIVE_ORDER: kotlin.Comparator<kotlin.String> { get; }
public val kotlin.Char.category: kotlin.text.CharCategory { get; }
public val kotlin.CharSequence.indices: kotlin.ranges.IntRange { get; }
public val kotlin.CharSequence.lastIndex: kotlin.Int { get; }
@@ -361,13 +363,25 @@ public inline fun kotlin.text.StringBuilder.insertRange(index: kotlin.Int, value
public fun kotlin.CharSequence.isBlank(): kotlin.Boolean
public fun kotlin.Char.isDefined(): kotlin.Boolean
public fun kotlin.Char.isDigit(): kotlin.Boolean
@kotlin.internal.InlineOnly
public inline fun kotlin.CharSequence.isEmpty(): kotlin.Boolean
public fun kotlin.Char.isHighSurrogate(): kotlin.Boolean
public fun kotlin.Char.isISOControl(): kotlin.Boolean
public fun kotlin.Char.isLetter(): kotlin.Boolean
public fun kotlin.Char.isLetterOrDigit(): kotlin.Boolean
public fun kotlin.Char.isLowSurrogate(): kotlin.Boolean
public fun kotlin.Char.isLowerCase(): kotlin.Boolean
@kotlin.internal.InlineOnly
public inline fun kotlin.CharSequence.isNotBlank(): kotlin.Boolean
@@ -382,6 +396,10 @@ public inline fun kotlin.CharSequence?.isNullOrEmpty(): kotlin.Boolean
public fun kotlin.Char.isSurrogate(): kotlin.Boolean
public fun kotlin.Char.isTitleCase(): kotlin.Boolean
public fun kotlin.Char.isUpperCase(): kotlin.Boolean
public fun kotlin.Char.isWhitespace(): kotlin.Boolean
public operator fun kotlin.CharSequence.iterator(): kotlin.collections.CharIterator
@@ -1178,6 +1196,75 @@ public interface Appendable {
public abstract fun append(value: kotlin.CharSequence?, startIndex: kotlin.Int, endIndex: kotlin.Int): kotlin.text.Appendable
}
public final enum class CharCategory : kotlin.Enum<kotlin.text.CharCategory> {
enum entry UNASSIGNED
enum entry UPPERCASE_LETTER
enum entry LOWERCASE_LETTER
enum entry TITLECASE_LETTER
enum entry MODIFIER_LETTER
enum entry OTHER_LETTER
enum entry NON_SPACING_MARK
enum entry ENCLOSING_MARK
enum entry COMBINING_SPACING_MARK
enum entry DECIMAL_DIGIT_NUMBER
enum entry LETTER_NUMBER
enum entry OTHER_NUMBER
enum entry SPACE_SEPARATOR
enum entry LINE_SEPARATOR
enum entry PARAGRAPH_SEPARATOR
enum entry CONTROL
enum entry FORMAT
enum entry PRIVATE_USE
enum entry SURROGATE
enum entry DASH_PUNCTUATION
enum entry START_PUNCTUATION
enum entry END_PUNCTUATION
enum entry CONNECTOR_PUNCTUATION
enum entry OTHER_PUNCTUATION
enum entry MATH_SYMBOL
enum entry CURRENCY_SYMBOL
enum entry MODIFIER_SYMBOL
enum entry OTHER_SYMBOL
enum entry INITIAL_QUOTE_PUNCTUATION
enum entry FINAL_QUOTE_PUNCTUATION
public final val code: kotlin.String { get; }
public final operator fun contains(char: kotlin.Char): kotlin.Boolean
public companion object of CharCategory {
}
}
@kotlin.SinceKotlin(version = "1.4")
@kotlin.WasExperimental(markerClass = {kotlin.ExperimentalStdlibApi::class})
public open class CharacterCodingException : kotlin.Exception {
+87
View File
@@ -1,6 +1,8 @@
@kotlin.SinceKotlin(version = "1.2")
public val kotlin.String.Companion.CASE_INSENSITIVE_ORDER: kotlin.Comparator<kotlin.String> { get; }
public val kotlin.Char.category: kotlin.text.CharCategory { get; }
public val kotlin.CharSequence.indices: kotlin.ranges.IntRange { get; }
public val kotlin.CharSequence.lastIndex: kotlin.Int { get; }
@@ -361,13 +363,25 @@ public inline fun kotlin.text.StringBuilder.insertRange(index: kotlin.Int, value
public fun kotlin.CharSequence.isBlank(): kotlin.Boolean
public fun kotlin.Char.isDefined(): kotlin.Boolean
public fun kotlin.Char.isDigit(): kotlin.Boolean
@kotlin.internal.InlineOnly
public inline fun kotlin.CharSequence.isEmpty(): kotlin.Boolean
public fun kotlin.Char.isHighSurrogate(): kotlin.Boolean
public fun kotlin.Char.isISOControl(): kotlin.Boolean
public fun kotlin.Char.isLetter(): kotlin.Boolean
public fun kotlin.Char.isLetterOrDigit(): kotlin.Boolean
public fun kotlin.Char.isLowSurrogate(): kotlin.Boolean
public fun kotlin.Char.isLowerCase(): kotlin.Boolean
@kotlin.internal.InlineOnly
public inline fun kotlin.CharSequence.isNotBlank(): kotlin.Boolean
@@ -382,6 +396,10 @@ public inline fun kotlin.CharSequence?.isNullOrEmpty(): kotlin.Boolean
public fun kotlin.Char.isSurrogate(): kotlin.Boolean
public fun kotlin.Char.isTitleCase(): kotlin.Boolean
public fun kotlin.Char.isUpperCase(): kotlin.Boolean
public fun kotlin.Char.isWhitespace(): kotlin.Boolean
public operator fun kotlin.CharSequence.iterator(): kotlin.collections.CharIterator
@@ -1178,6 +1196,75 @@ public interface Appendable {
public abstract fun append(value: kotlin.CharSequence?, startIndex: kotlin.Int, endIndex: kotlin.Int): kotlin.text.Appendable
}
public final enum class CharCategory : kotlin.Enum<kotlin.text.CharCategory> {
enum entry UNASSIGNED
enum entry UPPERCASE_LETTER
enum entry LOWERCASE_LETTER
enum entry TITLECASE_LETTER
enum entry MODIFIER_LETTER
enum entry OTHER_LETTER
enum entry NON_SPACING_MARK
enum entry ENCLOSING_MARK
enum entry COMBINING_SPACING_MARK
enum entry DECIMAL_DIGIT_NUMBER
enum entry LETTER_NUMBER
enum entry OTHER_NUMBER
enum entry SPACE_SEPARATOR
enum entry LINE_SEPARATOR
enum entry PARAGRAPH_SEPARATOR
enum entry CONTROL
enum entry FORMAT
enum entry PRIVATE_USE
enum entry SURROGATE
enum entry DASH_PUNCTUATION
enum entry START_PUNCTUATION
enum entry END_PUNCTUATION
enum entry CONNECTOR_PUNCTUATION
enum entry OTHER_PUNCTUATION
enum entry MATH_SYMBOL
enum entry CURRENCY_SYMBOL
enum entry MODIFIER_SYMBOL
enum entry OTHER_SYMBOL
enum entry INITIAL_QUOTE_PUNCTUATION
enum entry FINAL_QUOTE_PUNCTUATION
public final val code: kotlin.String { get; }
public final operator fun contains(char: kotlin.Char): kotlin.Boolean
public companion object of CharCategory {
}
}
@kotlin.SinceKotlin(version = "1.4")
@kotlin.WasExperimental(markerClass = {kotlin.ExperimentalStdlibApi::class})
public open class CharacterCodingException : kotlin.Exception {
@@ -63,7 +63,6 @@ expect enum class RegexOption {
// From char.kt
expect fun Char.isWhitespace(): Boolean
expect fun Char.isHighSurrogate(): Boolean
expect fun Char.isLowSurrogate(): Boolean
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 1343 ranges totally
private object Category {
val decodedRangeStart: IntArray
val decodedRangeCategory: IntArray
init {
val toBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
val fromBase64 = IntArray(128)
for (i in toBase64.indices) {
fromBase64[toBase64[i].toInt()] = i
}
// rangeStartDiff.length = 1482
val rangeStartDiff = "gBCFEDCKCDCaDDaDBhBCEEDDDDDEDXBHYBH5BRwBGDCHDCIDFHDCHFDCDEIRTEE7BGHDDJlCBbSEMOFGERwDEDDDDECEFCRBJhBFDCYFFCCzBvBjBBFC3BOhDBmBDGpBDDCtBBJIbEECLGDFCLDCgBBKVKEDiDDHCFECECKCEODBebC5CLBOKhBJDDDDWEBHFCFCPBZDEL1BVBSLPBgBB2BDBDICFBHKCCKCPDBHEDWBHEDDDDEDEDIBDGDCKCCGDDDCGECCWBFMDDCDEDDCHDDHKDDBKDBHFCWBFGFDBDDFEDBPDDKCHBGDCHEDWBFGFDCEDEDBHDDGDCKCGJEGDBFDDFDDDDDMEFDBFDCGBOKDFDFDCGFCXBQDDDDDBEGEDFDDKHBHDDGFCXBKBFCEFCFCHCHECCKDNCCHFCoBEDECFDDDDHDCCKJBGDCSDYBJEHBFDDEBIGKDCMuBFHEBGBIBKCkBFBFBXEIFJDFDGCKCEgBBDPEDGKKGECIBkBEOBDFFLBkBBIBEFFEClBrBCEBEGDBKGGDDDDDCHDENDCFEKDDlBDDFrBCDpKBECGEECpBBEChBBECGEECPB5BBECjCCDJUDQKG2CCGDsTCRBaCDrCDDIHNBEDLSDCJSCMLFCCM0BDHGFLBFDDKGKGEFDDBKGjBB1BHFChBDFmCKfDDDDDDCGDCFDKeCFLsBEaGKBDiBXDDD1BDGDEIGJEKGKGHBGCMF/BEBvBCEDDFHEKHKJJDDeDDGDKsBFEDCIEkBIICCDFKDDKeGCJHrBCDIIDBNBHEBEFDBFsB/BNBiBlB6BBF1EIiDJIGCGCIIIIGCGCIIIIOCIIIIIIDFEDDBFEDDDDEBDIFDDFEDBLFGCEEICFBJCDEDCLDKBFBKCCGDDKDDNDgBQNEBDMPFFDEDEBFFHECEBEEDFBEDDQjBCEDEFFCCJHBeEEfsIIEUCHCxCBeZoBGlCZLV8BuCW3FBJB2BIvDB4HOesBFCfKQgIjEW/BEgBCiIwBVCGnBCgBBpDvBBuBEDBHEFGCCjDCGEDCFCFlBDDF4BHCOBXJHBHBHBHBHBHBHBHBgBCECGHGEDIFBKCEDMEtBaB5CM2GaMEDDCKCGFCJEDFDDDC2CDDDB6CDCFrBB+CDEKgBkBMQfBKeIBPgBKnBPgKguGgC9vUDVB3jBD3BJoBGCsIBDQKCUuBDDKCcCCmCKCGIXJCNC/BBHGKDECEVFBEMCEEBqBDDGDFDXDCEBDGEG0BEICyBQCICKGSGDEBKcICXLCLBdDDBvBDECCDNCKECFCJKFBpBFEDCJDBICCKCEQBGDDByBEDCEFBYDCLEDDCKGCGCGJHBHBrBBEJDEwCjBIDCKGk9KMXExBEggCgoGuLCqDmBHMFFCKBNBFBIsDQRrLCQgCC2BoBMCCQGEGQDCQDDDDFDGDECEEFBnEEBFEDCKCDCaDDaDBFCKBtBCfDGCGCFEDDDDCECKDC"
val diff = decodeVarLenBase64(rangeStartDiff, fromBase64, 1342)
val start = IntArray(diff.size + 1)
for (i in diff.indices) {
start[i + 1] = start[i] + diff[i]
}
decodedRangeStart = start
// rangeCategory.length = 2033
val rangeCategory = "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"
decodedRangeCategory = decodeVarLenBase64(rangeCategory, fromBase64, 1343)
}
}
private fun categoryValueFrom(code: Int, ch: Int): Int {
return when {
code < 0x20 -> code
code < 0x400 -> if ((ch and 1) == 1) code shr 5 else code and 0x1f
else ->
when (ch % 3) {
2 -> code shr 10
1 -> (code shr 5) and 0x1f
else -> code and 0x1f
}
}
}
/**
* Returns the Unicode general category of this character as an Int.
*/
internal fun Char.getCategoryValue(): Int {
val ch = this.toInt()
val index = binarySearchRange(Category.decodedRangeStart, ch)
val start = Category.decodedRangeStart[index]
val code = Category.decodedRangeCategory[index]
val value = categoryValueFrom(code, ch - start)
return if (value == 17) CharCategory.UNASSIGNED.value else value
}
internal fun decodeVarLenBase64(base64: String, fromBase64: IntArray, resultLength: Int): IntArray {
val result = IntArray(resultLength)
var index = 0
var int = 0
var shift = 0
for (char in base64) {
val sixBit = fromBase64[char.toInt()]
int = int or ((sixBit and 0x1f) shl shift)
if (sixBit < 0x20) {
result[index++] = int
int = 0
shift = 0
} else {
shift += 5
}
}
return result
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 37 ranges totally
private object Digit {
internal val rangeStart = intArrayOf(
0x0030, 0x0660, 0x06f0, 0x07c0, 0x0966, 0x09e6, 0x0a66, 0x0ae6, 0x0b66, 0x0be6, 0x0c66, 0x0ce6, 0x0d66, 0x0de6, 0x0e50, 0x0ed0, 0x0f20, 0x1040, 0x1090, 0x17e0,
0x1810, 0x1946, 0x19d0, 0x1a80, 0x1a90, 0x1b50, 0x1bb0, 0x1c40, 0x1c50, 0xa620, 0xa8d0, 0xa900, 0xa9d0, 0xa9f0, 0xaa50, 0xabf0, 0xff10,
)
}
internal fun binarySearchRange(array: IntArray, needle: Int): Int {
var bottom = 0
var top = array.size - 1
var middle = -1
var value = 0
while (bottom <= top) {
middle = (bottom + top) / 2
value = array[middle]
if (needle > value)
bottom = middle + 1
else if (needle == value)
return middle
else
top = middle - 1
}
return middle - (if (needle < value) 1 else 0)
}
/**
* Returns `true` if this character is a digit.
*/
internal fun Char.isDigitImpl(): Boolean {
val ch = this.toInt()
val index = binarySearchRange(Digit.rangeStart, ch)
val high = Digit.rangeStart[index] + 9
return ch <= high
}
@@ -0,0 +1,114 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 222 ranges totally
private object Letter {
val decodedRangeStart: IntArray
val decodedRangeLength: IntArray
val decodedRangeCategory: IntArray
init {
val toBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
val fromBase64 = IntArray(128)
for (i in toBase64.indices) {
fromBase64[toBase64[i].toInt()] = i
}
// rangeStartDiff.length = 356
val rangeStartDiff = "hCgBpCQGYHZH5BRpBPPPPPPRMP5BPPlCPP6BkEPPPPcPXPzBvBrB3BOiDoBHwD+E3DauCnFmBmB2D6E1BlBTiBmBlBP5BhBiBrBvBjBqBnBPRtBiCmCtBlB0BmB5BiB7BmBgEmChBZgCoEoGVpBSfRhBPqKQ2BwBYoFgB4CJuTiEvBuCuDrF5DgEgFlJ1DgFmBQtBsBRGsB+BPiBlD1EIjDPRPPPQPPPPPGQSQS/DxENVNU+B9zCwBwBPPCkDPNnBPqDYY1R8B7FkFgTgwGgwUwmBgKwBuBScmEP/BPPPPPPrBP8B7F1B/ErBqC6B7BiBmBfQsBUwCw/KwqIwLwETPcPjQgJxFgBlBsD"
val diff = decodeVarLenBase64(rangeStartDiff, fromBase64, 222)
val start = IntArray(diff.size)
for (i in diff.indices) {
if (i == 0) start[i] = diff[i]
else start[i] = start[i - 1] + diff[i]
}
decodedRangeStart = start
// rangeLength.length = 328
val rangeLength = "aaMBXHYH5BRpBPPPPPPRMP5BPPlCPPzBDOOPPcPXPzBvBjB3BOhDmBBpB7DoDYxB+EiBP1DoExBkBQhBekBPmBgBhBctBiBMWOOXhCsBpBkBUV3Ba4BkB0DlCgBXgBtD4FSdBfPhBPpKP0BvBXjEQ2CGsT8DhBtCqDpFvD1D3E0IrD2EkBJrBDOBsB+BPiBlB1EIjDPPPPPPPPPPPGPPMNLsBNPNPKCvBvBPPCkDPBmBPhDXXgD4B6FzEgDguG9vUtkB9JcuBSckEP/BPPPPPPBPf4FrBjEhBpC3B5BKaWPrBOwCk/KsCuLqDHPbPxPsFtEaaqDL"
decodedRangeLength = decodeVarLenBase64(rangeLength, fromBase64, 222)
// rangeCategory.length = 959
val rangeCategory = "GFjgggUHGGFFZZZmzpz5qB6s6020B60ptltB6smt2sB60mz22B1+vv+8BZZ5s2850BW5q1ymtB506smzBF3q1q1qB1q1q1+Bgii4wDTm74g3KiggxqM60q1q1Bq1o1q1BF1qlrqrBZ2q5wprBGFZWWZGHFsjiooLowgmOowjkwCkgoiIk7ligGogiioBkwkiYkzj2oNoi+sbkwj04DghhkQ8wgiYkgoioDsgnkwC4gikQ//v+85BkwvoIsgoyI4yguI0whiwEowri4CoghsJowgqYowgm4DkwgsY/nwnzPowhmYkg6wI8yggZswikwHgxgmIoxgqYkwgk4DkxgmIkgoioBsgssoBgzgyI8g9gL8g9kI0wgwJoxgkoC0wgioFkw/wI0w53iF4gioYowjmgBHGq1qkgwBF1q1q8qBHwghuIwghyKk0goQkwgoQk3goQHGFHkyg0pBgxj6IoinkxDswno7Ikwhz9Bo0gioB8z48Rwli0xN0mpjoX8w78pDwltoqKHFGGwwgsIHFH3q1q16BFHWFZ1q10q1B2qlwq1B1q10q1B2q1yq1B6q1gq1Biq1qhxBir1qp1Bqt1q1qB1g1q1+B//3q16B///q1qBH/qlqq9Bholqq9B1i00a1q10qD1op1HkwmigEigiy6Cptogq1Bixo1kDq7/j00B2qgoBWGFm1lz50B6s5q1+BGWhggzhwBFFhgk4//Bo2jigE8wguI8wguI8wgugUog1qoB4qjmIwwi2KgkYHHH4lBgiFWkgIWoghssMmz5smrBZ3q1y50B5sm7gzBtz1smzB5smz50BqzqtmzB5sgzqzBF2/9//5BowgoIwmnkzPkwgk4C8ys65BkgoqI0wgy6FghquZo2giY0ghiIsgh24B4ghsQ8QF/v1q1OFs0O8iCHHF1qggz/B8wg6Iznv+//B08QgohsjK0QGFk7hsQ4gB"
decodedRangeCategory = decodeVarLenBase64(rangeCategory, fromBase64, 222)
}
}
/**
* Returns `true` if this character is a letter.
*/
internal fun Char.isLetterImpl(): Boolean {
return getLetterType() != 0
}
/**
* Returns `true` if this character is a lower case letter.
*/
internal fun Char.isLowerCaseImpl(): Boolean {
return getLetterType() == 1
}
/**
* Returns `true` if this character is an upper case letter.
*/
internal fun Char.isUpperCaseImpl(): Boolean {
return getLetterType() == 2
}
/**
* Returns
* - `1` if the character is a lower case letter,
* - `2` if the character is an upper case letter,
* - `3` if the character is a letter but not a lower or upper case letter,
* - `0` otherwise.
*/
private fun Char.getLetterType(): Int {
val ch = this.toInt()
val index = binarySearchRange(Letter.decodedRangeStart, ch)
val rangeStart = Letter.decodedRangeStart[index]
val rangeEnd = rangeStart + Letter.decodedRangeLength[index] - 1
val code = Letter.decodedRangeCategory[index]
if (ch > rangeEnd) {
return 0
}
val lastTwoBits = code and 0x3
if (lastTwoBits == 0) { // gap pattern
var shift = 2
var threshold = rangeStart
for (i in 0..1) {
threshold += (code shr shift) and 0x7f
if (threshold > ch) {
return 3
}
shift += 7
threshold += (code shr shift) and 0x7f
if (threshold > ch) {
return 0
}
shift += 7
}
return 3
}
if (code <= 0x7) {
return lastTwoBits
}
val distance = (ch - rangeStart)
val shift = if (code <= 0x1F) distance % 2 else distance
return (code shr (2 * shift)) and 0x3
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 9 ranges totally
/**
* Returns `true` if this character is a whitespace.
*/
internal fun Char.isWhitespaceImpl(): Boolean {
val ch = this.toInt()
return ch in 0x0009..0x000d
|| ch in 0x001c..0x0020
|| ch == 0x00a0
|| ch > 0x1000 && (
ch == 0x1680
|| ch in 0x2000..0x200a
|| ch == 0x2028
|| ch == 0x2029
|| ch == 0x202f
|| ch == 0x205f
|| ch == 0x3000
)
}
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 1343 ranges totally
private object Category {
val decodedRangeStart: IntArray
val decodedRangeCategory: IntArray
init {
val toBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
val fromBase64 = IntArray(128)
for (i in toBase64.indices) {
fromBase64[toBase64[i].toInt()] = i
}
// rangeStartDiff.length = 1482
val rangeStartDiff = "gBCFEDCKCDCaDDaDBhBCEEDDDDDEDXBHYBH5BRwBGDCHDCIDFHDCHFDCDEIRTEE7BGHDDJlCBbSEMOFGERwDEDDDDECEFCRBJhBFDCYFFCCzBvBjBBFC3BOhDBmBDGpBDDCtBBJIbEECLGDFCLDCgBBKVKEDiDDHCFECECKCEODBebC5CLBOKhBJDDDDWEBHFCFCPBZDEL1BVBSLPBgBB2BDBDICFBHKCCKCPDBHEDWBHEDDDDEDEDIBDGDCKCCGDDDCGECCWBFMDDCDEDDCHDDHKDDBKDBHFCWBFGFDBDDFEDBPDDKCHBGDCHEDWBFGFDCEDEDBHDDGDCKCGJEGDBFDDFDDDDDMEFDBFDCGBOKDFDFDCGFCXBQDDDDDBEGEDFDDKHBHDDGFCXBKBFCEFCFCHCHECCKDNCCHFCoBEDECFDDDDHDCCKJBGDCSDYBJEHBFDDEBIGKDCMuBFHEBGBIBKCkBFBFBXEIFJDFDGCKCEgBBDPEDGKKGECIBkBEOBDFFLBkBBIBEFFEClBrBCEBEGDBKGGDDDDDCHDENDCFEKDDlBDDFrBCDpKBECGEECpBBEChBBECGEECPB5BBECjCCDJUDQKG2CCGDsTCRBaCDrCDDIHNBEDLSDCJSCMLFCCM0BDHGFLBFDDKGKGEFDDBKGjBB1BHFChBDFmCKfDDDDDDCGDCFDKeCFLsBEaGKBDiBXDDD1BDGDEIGJEKGKGHBGCMF/BEBvBCEDDFHEKHKJJDDeDDGDKsBFEDCIEkBIICCDFKDDKeGCJHrBCDIIDBNBHEBEFDBFsB/BNBiBlB6BBF1EIiDJIGCGCIIIIGCGCIIIIOCIIIIIIDFEDDBFEDDDDEBDIFDDFEDBLFGCEEICFBJCDEDCLDKBFBKCCGDDKDDNDgBQNEBDMPFFDEDEBFFHECEBEEDFBEDDQjBCEDEFFCCJHBeEEfsIIEUCHCxCBeZoBGlCZLV8BuCW3FBJB2BIvDB4HOesBFCfKQgIjEW/BEgBCiIwBVCGnBCgBBpDvBBuBEDBHEFGCCjDCGEDCFCFlBDDF4BHCOBXJHBHBHBHBHBHBHBHBgBCECGHGEDIFBKCEDMEtBaB5CM2GaMEDDCKCGFCJEDFDDDC2CDDDB6CDCFrBB+CDEKgBkBMQfBKeIBPgBKnBPgKguGgC9vUDVB3jBD3BJoBGCsIBDQKCUuBDDKCcCCmCKCGIXJCNC/BBHGKDECEVFBEMCEEBqBDDGDFDXDCEBDGEG0BEICyBQCICKGSGDEBKcICXLCLBdDDBvBDECCDNCKECFCJKFBpBFEDCJDBICCKCEQBGDDByBEDCEFBYDCLEDDCKGCGCGJHBHBrBBEJDEwCjBIDCKGk9KMXExBEggCgoGuLCqDmBHMFFCKBNBFBIsDQRrLCQgCC2BoBMCCQGEGQDCQDDDDFDGDECEEFBnEEBFEDCKCDCaDDaDBFCKBtBCfDGCGCFEDDDDCECKDC"
val diff = decodeVarLenBase64(rangeStartDiff, fromBase64, 1342)
val start = IntArray(diff.size + 1)
for (i in diff.indices) {
start[i + 1] = start[i] + diff[i]
}
decodedRangeStart = start
// rangeCategory.length = 2033
val rangeCategory = "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"
decodedRangeCategory = decodeVarLenBase64(rangeCategory, fromBase64, 1343)
}
}
private fun categoryValueFrom(code: Int, ch: Int): Int {
return when {
code < 0x20 -> code
code < 0x400 -> if ((ch and 1) == 1) code shr 5 else code and 0x1f
else ->
when (ch % 3) {
2 -> code shr 10
1 -> (code shr 5) and 0x1f
else -> code and 0x1f
}
}
}
/**
* Returns the Unicode general category of this character as an Int.
*/
internal fun Char.getCategoryValue(): Int {
val ch = this.toInt()
val index = binarySearchRange(Category.decodedRangeStart, ch)
val start = Category.decodedRangeStart[index]
val code = Category.decodedRangeCategory[index]
val value = categoryValueFrom(code, ch - start)
return if (value == 17) CharCategory.UNASSIGNED.value else value
}
internal fun decodeVarLenBase64(base64: String, fromBase64: IntArray, resultLength: Int): IntArray {
val result = IntArray(resultLength)
var index = 0
var int = 0
var shift = 0
for (char in base64) {
val sixBit = fromBase64[char.toInt()]
int = int or ((sixBit and 0x1f) shl shift)
if (sixBit < 0x20) {
result[index++] = int
int = 0
shift = 0
} else {
shift += 5
}
}
return result
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 37 ranges totally
private object Digit {
internal val rangeStart = intArrayOf(
0x0030, 0x0660, 0x06f0, 0x07c0, 0x0966, 0x09e6, 0x0a66, 0x0ae6, 0x0b66, 0x0be6, 0x0c66, 0x0ce6, 0x0d66, 0x0de6, 0x0e50, 0x0ed0, 0x0f20, 0x1040, 0x1090, 0x17e0,
0x1810, 0x1946, 0x19d0, 0x1a80, 0x1a90, 0x1b50, 0x1bb0, 0x1c40, 0x1c50, 0xa620, 0xa8d0, 0xa900, 0xa9d0, 0xa9f0, 0xaa50, 0xabf0, 0xff10,
)
}
internal fun binarySearchRange(array: IntArray, needle: Int): Int {
var bottom = 0
var top = array.size - 1
var middle = -1
var value = 0
while (bottom <= top) {
middle = (bottom + top) / 2
value = array[middle]
if (needle > value)
bottom = middle + 1
else if (needle == value)
return middle
else
top = middle - 1
}
return middle - (if (needle < value) 1 else 0)
}
/**
* Returns `true` if this character is a digit.
*/
internal fun Char.isDigitImpl(): Boolean {
val ch = this.toInt()
val index = binarySearchRange(Digit.rangeStart, ch)
val high = Digit.rangeStart[index] + 9
return ch <= high
}
@@ -0,0 +1,114 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 222 ranges totally
private object Letter {
val decodedRangeStart: IntArray
val decodedRangeLength: IntArray
val decodedRangeCategory: IntArray
init {
val toBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
val fromBase64 = IntArray(128)
for (i in toBase64.indices) {
fromBase64[toBase64[i].toInt()] = i
}
// rangeStartDiff.length = 356
val rangeStartDiff = "hCgBpCQGYHZH5BRpBPPPPPPRMP5BPPlCPP6BkEPPPPcPXPzBvBrB3BOiDoBHwD+E3DauCnFmBmB2D6E1BlBTiBmBlBP5BhBiBrBvBjBqBnBPRtBiCmCtBlB0BmB5BiB7BmBgEmChBZgCoEoGVpBSfRhBPqKQ2BwBYoFgB4CJuTiEvBuCuDrF5DgEgFlJ1DgFmBQtBsBRGsB+BPiBlD1EIjDPRPPPQPPPPPGQSQS/DxENVNU+B9zCwBwBPPCkDPNnBPqDYY1R8B7FkFgTgwGgwUwmBgKwBuBScmEP/BPPPPPPrBP8B7F1B/ErBqC6B7BiBmBfQsBUwCw/KwqIwLwETPcPjQgJxFgBlBsD"
val diff = decodeVarLenBase64(rangeStartDiff, fromBase64, 222)
val start = IntArray(diff.size)
for (i in diff.indices) {
if (i == 0) start[i] = diff[i]
else start[i] = start[i - 1] + diff[i]
}
decodedRangeStart = start
// rangeLength.length = 328
val rangeLength = "aaMBXHYH5BRpBPPPPPPRMP5BPPlCPPzBDOOPPcPXPzBvBjB3BOhDmBBpB7DoDYxB+EiBP1DoExBkBQhBekBPmBgBhBctBiBMWOOXhCsBpBkBUV3Ba4BkB0DlCgBXgBtD4FSdBfPhBPpKP0BvBXjEQ2CGsT8DhBtCqDpFvD1D3E0IrD2EkBJrBDOBsB+BPiBlB1EIjDPPPPPPPPPPPGPPMNLsBNPNPKCvBvBPPCkDPBmBPhDXXgD4B6FzEgDguG9vUtkB9JcuBSckEP/BPPPPPPBPf4FrBjEhBpC3B5BKaWPrBOwCk/KsCuLqDHPbPxPsFtEaaqDL"
decodedRangeLength = decodeVarLenBase64(rangeLength, fromBase64, 222)
// rangeCategory.length = 959
val rangeCategory = "GFjgggUHGGFFZZZmzpz5qB6s6020B60ptltB6smt2sB60mz22B1+vv+8BZZ5s2850BW5q1ymtB506smzBF3q1q1qB1q1q1+Bgii4wDTm74g3KiggxqM60q1q1Bq1o1q1BF1qlrqrBZ2q5wprBGFZWWZGHFsjiooLowgmOowjkwCkgoiIk7ligGogiioBkwkiYkzj2oNoi+sbkwj04DghhkQ8wgiYkgoioDsgnkwC4gikQ//v+85BkwvoIsgoyI4yguI0whiwEowri4CoghsJowgqYowgm4DkwgsY/nwnzPowhmYkg6wI8yggZswikwHgxgmIoxgqYkwgk4DkxgmIkgoioBsgssoBgzgyI8g9gL8g9kI0wgwJoxgkoC0wgioFkw/wI0w53iF4gioYowjmgBHGq1qkgwBF1q1q8qBHwghuIwghyKk0goQkwgoQk3goQHGFHkyg0pBgxj6IoinkxDswno7Ikwhz9Bo0gioB8z48Rwli0xN0mpjoX8w78pDwltoqKHFGGwwgsIHFH3q1q16BFHWFZ1q10q1B2qlwq1B1q10q1B2q1yq1B6q1gq1Biq1qhxBir1qp1Bqt1q1qB1g1q1+B//3q16B///q1qBH/qlqq9Bholqq9B1i00a1q10qD1op1HkwmigEigiy6Cptogq1Bixo1kDq7/j00B2qgoBWGFm1lz50B6s5q1+BGWhggzhwBFFhgk4//Bo2jigE8wguI8wguI8wgugUog1qoB4qjmIwwi2KgkYHHH4lBgiFWkgIWoghssMmz5smrBZ3q1y50B5sm7gzBtz1smzB5smz50BqzqtmzB5sgzqzBF2/9//5BowgoIwmnkzPkwgk4C8ys65BkgoqI0wgy6FghquZo2giY0ghiIsgh24B4ghsQ8QF/v1q1OFs0O8iCHHF1qggz/B8wg6Iznv+//B08QgohsjK0QGFk7hsQ4gB"
decodedRangeCategory = decodeVarLenBase64(rangeCategory, fromBase64, 222)
}
}
/**
* Returns `true` if this character is a letter.
*/
internal fun Char.isLetterImpl(): Boolean {
return getLetterType() != 0
}
/**
* Returns `true` if this character is a lower case letter.
*/
internal fun Char.isLowerCaseImpl(): Boolean {
return getLetterType() == 1
}
/**
* Returns `true` if this character is an upper case letter.
*/
internal fun Char.isUpperCaseImpl(): Boolean {
return getLetterType() == 2
}
/**
* Returns
* - `1` if the character is a lower case letter,
* - `2` if the character is an upper case letter,
* - `3` if the character is a letter but not a lower or upper case letter,
* - `0` otherwise.
*/
private fun Char.getLetterType(): Int {
val ch = this.toInt()
val index = binarySearchRange(Letter.decodedRangeStart, ch)
val rangeStart = Letter.decodedRangeStart[index]
val rangeEnd = rangeStart + Letter.decodedRangeLength[index] - 1
val code = Letter.decodedRangeCategory[index]
if (ch > rangeEnd) {
return 0
}
val lastTwoBits = code and 0x3
if (lastTwoBits == 0) { // gap pattern
var shift = 2
var threshold = rangeStart
for (i in 0..1) {
threshold += (code shr shift) and 0x7f
if (threshold > ch) {
return 3
}
shift += 7
threshold += (code shr shift) and 0x7f
if (threshold > ch) {
return 0
}
shift += 7
}
return 3
}
if (code <= 0x7) {
return lastTwoBits
}
val distance = (ch - rangeStart)
val shift = if (code <= 0x1F) distance % 2 else distance
return (code shr (2 * shift)) and 0x3
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
//
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateUnicodeData.kt
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
//
// 9 ranges totally
/**
* Returns `true` if this character is a whitespace.
*/
internal fun Char.isWhitespaceImpl(): Boolean {
val ch = this.toInt()
return ch in 0x0009..0x000d
|| ch in 0x001c..0x0020
|| ch == 0x00a0
|| ch > 0x1000 && (
ch == 0x1680
|| ch in 0x2000..0x200a
|| ch == 0x2028
|| ch == 0x2029
|| ch == 0x202f
|| ch == 0x205f
|| ch == 0x3000
)
}
@@ -0,0 +1,172 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
public actual enum class CharCategory(internal val value: Int, public actual val code: String) {
/**
* General category "Cn" in the Unicode specification.
*/
UNASSIGNED(0, "Cn"),
/**
* General category "Lu" in the Unicode specification.
*/
UPPERCASE_LETTER(1, "Lu"),
/**
* General category "Ll" in the Unicode specification.
*/
LOWERCASE_LETTER(2, "Ll"),
/**
* General category "Lt" in the Unicode specification.
*/
TITLECASE_LETTER(3, "Lt"),
/**
* General category "Lm" in the Unicode specification.
*/
MODIFIER_LETTER(4, "Lm"),
/**
* General category "Lo" in the Unicode specification.
*/
OTHER_LETTER(5, "Lo"),
/**
* General category "Mn" in the Unicode specification.
*/
NON_SPACING_MARK(6, "Mn"),
/**
* General category "Me" in the Unicode specification.
*/
ENCLOSING_MARK(7, "Me"),
/**
* General category "Mc" in the Unicode specification.
*/
COMBINING_SPACING_MARK(8, "Mc"),
/**
* General category "Nd" in the Unicode specification.
*/
DECIMAL_DIGIT_NUMBER(9, "Nd"),
/**
* General category "Nl" in the Unicode specification.
*/
LETTER_NUMBER(10, "Nl"),
/**
* General category "No" in the Unicode specification.
*/
OTHER_NUMBER(11, "No"),
/**
* General category "Zs" in the Unicode specification.
*/
SPACE_SEPARATOR(12, "Zs"),
/**
* General category "Zl" in the Unicode specification.
*/
LINE_SEPARATOR(13, "Zl"),
/**
* General category "Zp" in the Unicode specification.
*/
PARAGRAPH_SEPARATOR(14, "Zp"),
/**
* General category "Cc" in the Unicode specification.
*/
CONTROL(15, "Cc"),
/**
* General category "Cf" in the Unicode specification.
*/
FORMAT(16, "Cf"),
/**
* General category "Co" in the Unicode specification.
*/
PRIVATE_USE(18, "Co"),
/**
* General category "Cs" in the Unicode specification.
*/
SURROGATE(19, "Cs"),
/**
* General category "Pd" in the Unicode specification.
*/
DASH_PUNCTUATION(20, "Pd"),
/**
* General category "Ps" in the Unicode specification.
*/
START_PUNCTUATION(21, "Ps"),
/**
* General category "Pe" in the Unicode specification.
*/
END_PUNCTUATION(22, "Pe"),
/**
* General category "Pc" in the Unicode specification.
*/
CONNECTOR_PUNCTUATION(23, "Pc"),
/**
* General category "Po" in the Unicode specification.
*/
OTHER_PUNCTUATION(24, "Po"),
/**
* General category "Sm" in the Unicode specification.
*/
MATH_SYMBOL(25, "Sm"),
/**
* General category "Sc" in the Unicode specification.
*/
CURRENCY_SYMBOL(26, "Sc"),
/**
* General category "Sk" in the Unicode specification.
*/
MODIFIER_SYMBOL(27, "Sk"),
/**
* General category "So" in the Unicode specification.
*/
OTHER_SYMBOL(28, "So"),
/**
* General category "Pi" in the Unicode specification.
*/
INITIAL_QUOTE_PUNCTUATION(29, "Pi"),
/**
* General category "Pf" in the Unicode specification.
*/
FINAL_QUOTE_PUNCTUATION(30, "Pf");
/**
* Returns `true` if [char] character belongs to this category.
*/
public actual operator fun contains(char: Char): Boolean = char.getCategoryValue() == this.value
companion object {
internal fun valueOf(category: Int): CharCategory =
when (category) {
in 0..16 -> values()[category]
in 18..30 -> values()[category - 1]
else -> throw IllegalArgumentException("Category #$category is not defined.")
}
}
}
+139 -3
View File
@@ -5,9 +5,6 @@
package kotlin.text
// actually \s is enough to match all whitespace, but \xA0 added because of different regexp behavior of Rhino used in Selenium tests
public actual fun Char.isWhitespace(): Boolean = toString().matches("[\\s\\xA0]")
/**
* Converts this character to lower case using Unicode mapping rules of the invariant locale.
*/
@@ -91,3 +88,142 @@ public actual fun Char.isHighSurrogate(): Boolean = this in Char.MIN_HIGH_SURROG
* Returns `true` if this character is a Unicode low-surrogate code unit (also known as trailing-surrogate code unit).
*/
public actual fun Char.isLowSurrogate(): Boolean = this in Char.MIN_LOW_SURROGATE..Char.MAX_LOW_SURROGATE
/**
* Returns the Unicode general category of this character.
*/
public actual val Char.category: CharCategory
get() = CharCategory.valueOf(getCategoryValue())
/**
* Returns `true` if this character (Unicode code point) is defined in Unicode.
*
* A character is considered to be defined in Unicode if its [category] is not [CharCategory.UNASSIGNED].
*/
public actual fun Char.isDefined(): Boolean {
if (this < '\u0080') {
return true
}
return getCategoryValue() != CharCategory.UNASSIGNED.value
}
/**
* Returns `true` if this character is a letter.
*
* A character is considered to be a letter if its [category] is [CharCategory.UPPERCASE_LETTER],
* [CharCategory.LOWERCASE_LETTER], [CharCategory.TITLECASE_LETTER], [CharCategory.MODIFIER_LETTER], or [CharCategory.OTHER_LETTER].
*
* @sample samples.text.Chars.isLetter
*/
public actual fun Char.isLetter(): Boolean {
if (this in 'a'..'z' || this in 'A'..'Z') {
return true
}
if (this < '\u0080') {
return false
}
return isLetterImpl()
}
/**
* Returns `true` if this character is a letter or digit.
*
* @see isLetter
* @see isDigit
*
* @sample samples.text.Chars.isLetterOrDigit
*/
public actual fun Char.isLetterOrDigit(): Boolean {
if (this in 'a'..'z' || this in 'A'..'Z' || this in '0'..'9') {
return true
}
if (this < '\u0080') {
return false
}
return isDigitImpl() || isLetterImpl()
}
/**
* Returns `true` if this character is a digit.
*
* A character is considered to be a digit if its [category] is [CharCategory.DECIMAL_DIGIT_NUMBER].
*
* @sample samples.text.Chars.isDigit
*/
public actual fun Char.isDigit(): Boolean {
if (this in '0'..'9') {
return true
}
if (this < '\u0080') {
return false
}
return isDigitImpl()
}
/**
* Returns `true` if this character is an upper case letter.
*
* A character is considered to be an upper case letter if its [category] is [CharCategory.UPPERCASE_LETTER].
*
* @sample samples.text.Chars.isUpperCase
*/
public actual fun Char.isUpperCase(): Boolean {
if (this in 'A'..'Z') {
return true
}
if (this < '\u0080') {
return false
}
return isUpperCaseImpl()
}
/**
* Returns `true` if this character is a lower case letter.
*
* A character is considered to be a lower case letter if its [category] is [CharCategory.LOWERCASE_LETTER].
*
* @sample samples.text.Chars.isLowerCase
*/
public actual fun Char.isLowerCase(): Boolean {
if (this in 'a'..'z') {
return true
}
if (this < '\u0080') {
return false
}
return isLowerCaseImpl()
}
/**
* Returns `true` if this character is a title case letter.
*
* A character is considered to be a title case letter if its [category] is [CharCategory.TITLECASE_LETTER].
*
* @sample samples.text.Chars.isTitleCase
*/
public actual fun Char.isTitleCase(): Boolean {
if (this < '\u0080') {
return false
}
return getCategoryValue() == CharCategory.TITLECASE_LETTER.value
}
/**
* Returns `true` if this character is an ISO control character.
*
* A character is considered to be an ISO control character if its [category] is [CharCategory.CONTROL].
*
* @sample samples.text.Chars.isISOControl
*/
public actual fun Char.isISOControl(): Boolean {
return this <= '\u001F' || this in '\u007F'..'\u009F'
}
/**
* Determines whether a character is whitespace according to the Unicode standard.
* Returns `true` if the character is whitespace.
*
* @sample samples.text.Chars.isWhitespace
*/
public actual fun Char.isWhitespace(): Boolean = isWhitespaceImpl()
@@ -0,0 +1,177 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
public actual enum class CharCategory(public val value: Int, public actual val code: String) {
/**
* General category "Cn" in the Unicode specification.
*/
UNASSIGNED(0, "Cn"),
/**
* General category "Lu" in the Unicode specification.
*/
UPPERCASE_LETTER(1, "Lu"),
/**
* General category "Ll" in the Unicode specification.
*/
LOWERCASE_LETTER(2, "Ll"),
/**
* General category "Lt" in the Unicode specification.
*/
TITLECASE_LETTER(3, "Lt"),
/**
* General category "Lm" in the Unicode specification.
*/
MODIFIER_LETTER(4, "Lm"),
/**
* General category "Lo" in the Unicode specification.
*/
OTHER_LETTER(5, "Lo"),
/**
* General category "Mn" in the Unicode specification.
*/
NON_SPACING_MARK(6, "Mn"),
/**
* General category "Me" in the Unicode specification.
*/
ENCLOSING_MARK(7, "Me"),
/**
* General category "Mc" in the Unicode specification.
*/
COMBINING_SPACING_MARK(8, "Mc"),
/**
* General category "Nd" in the Unicode specification.
*/
DECIMAL_DIGIT_NUMBER(9, "Nd"),
/**
* General category "Nl" in the Unicode specification.
*/
LETTER_NUMBER(10, "Nl"),
/**
* General category "No" in the Unicode specification.
*/
OTHER_NUMBER(11, "No"),
/**
* General category "Zs" in the Unicode specification.
*/
SPACE_SEPARATOR(12, "Zs"),
/**
* General category "Zl" in the Unicode specification.
*/
LINE_SEPARATOR(13, "Zl"),
/**
* General category "Zp" in the Unicode specification.
*/
PARAGRAPH_SEPARATOR(14, "Zp"),
/**
* General category "Cc" in the Unicode specification.
*/
CONTROL(15, "Cc"),
/**
* General category "Cf" in the Unicode specification.
*/
FORMAT(16, "Cf"),
/**
* General category "Co" in the Unicode specification.
*/
PRIVATE_USE(18, "Co"),
/**
* General category "Cs" in the Unicode specification.
*/
SURROGATE(19, "Cs"),
/**
* General category "Pd" in the Unicode specification.
*/
DASH_PUNCTUATION(20, "Pd"),
/**
* General category "Ps" in the Unicode specification.
*/
START_PUNCTUATION(21, "Ps"),
/**
* General category "Pe" in the Unicode specification.
*/
END_PUNCTUATION(22, "Pe"),
/**
* General category "Pc" in the Unicode specification.
*/
CONNECTOR_PUNCTUATION(23, "Pc"),
/**
* General category "Po" in the Unicode specification.
*/
OTHER_PUNCTUATION(24, "Po"),
/**
* General category "Sm" in the Unicode specification.
*/
MATH_SYMBOL(25, "Sm"),
/**
* General category "Sc" in the Unicode specification.
*/
CURRENCY_SYMBOL(26, "Sc"),
/**
* General category "Sk" in the Unicode specification.
*/
MODIFIER_SYMBOL(27, "Sk"),
/**
* General category "So" in the Unicode specification.
*/
OTHER_SYMBOL(28, "So"),
/**
* General category "Pi" in the Unicode specification.
*/
INITIAL_QUOTE_PUNCTUATION(29, "Pi"),
/**
* General category "Pf" in the Unicode specification.
*/
FINAL_QUOTE_PUNCTUATION(30, "Pf");
/**
* Returns `true` if [char] character belongs to this category.
*/
public actual operator fun contains(char: Char): Boolean = Character.getType(char) == this.value
companion object {
/**
* Returns the [CharCategory] corresponding to the specified [category] that represents a Java general category constant.
*
* @throws IllegalArgumentException if the [category] does not represent a Java general category constant.
*/
public fun valueOf(category: Int): CharCategory =
when (category) {
in 0..16 -> values()[category]
in 18..30 -> values()[category - 1]
else -> throw IllegalArgumentException("Category #$category is not defined.")
}
}
}
+32 -14
View File
@@ -10,32 +10,51 @@ package kotlin.text
import java.util.Locale
/**
* Returns the Unicode general category of this character.
*/
public actual val Char.category: CharCategory
get() = CharCategory.valueOf(Character.getType(this))
/**
* Returns `true` if this character (Unicode code point) is defined in Unicode.
*
* A character is considered to be defined in Unicode if its [category] is not [CharCategory.UNASSIGNED].
*/
@kotlin.internal.InlineOnly
public inline fun Char.isDefined(): Boolean = Character.isDefined(this)
public actual inline fun Char.isDefined(): Boolean = Character.isDefined(this)
/**
* Returns `true` if this character is a letter.
*
* A character is considered to be a letter if its [category] is [CharCategory.UPPERCASE_LETTER],
* [CharCategory.LOWERCASE_LETTER], [CharCategory.TITLECASE_LETTER], [CharCategory.MODIFIER_LETTER], or [CharCategory.OTHER_LETTER].
*
* @sample samples.text.Chars.isLetter
*/
@kotlin.internal.InlineOnly
public inline fun Char.isLetter(): Boolean = Character.isLetter(this)
public actual inline fun Char.isLetter(): Boolean = Character.isLetter(this)
/**
* Returns `true` if this character is a letter or digit.
*
* @see isLetter
* @see isDigit
*
* @sample samples.text.Chars.isLetterOrDigit
*/
@kotlin.internal.InlineOnly
public inline fun Char.isLetterOrDigit(): Boolean = Character.isLetterOrDigit(this)
public actual inline fun Char.isLetterOrDigit(): Boolean = Character.isLetterOrDigit(this)
/**
* Returns `true` if this character (Unicode code point) is a digit.
* Returns `true` if this character is a digit.
*
* A character is considered to be a digit if its [category] is [CharCategory.DECIMAL_DIGIT_NUMBER].
*
* @sample samples.text.Chars.isDigit
*/
@kotlin.internal.InlineOnly
public inline fun Char.isDigit(): Boolean = Character.isDigit(this)
public actual inline fun Char.isDigit(): Boolean = Character.isDigit(this)
/**
@@ -47,10 +66,13 @@ public inline fun Char.isIdentifierIgnorable(): Boolean = Character.isIdentifier
/**
* Returns `true` if this character is an ISO control character.
*
* A character is considered to be an ISO control character if its [category] is [CharCategory.CONTROL].
*
* @sample samples.text.Chars.isISOControl
*/
@kotlin.internal.InlineOnly
public inline fun Char.isISOControl(): Boolean = Character.isISOControl(this)
public actual inline fun Char.isISOControl(): Boolean = Character.isISOControl(this)
/**
* Returns `true` if this character (Unicode code point) may be part of a Java identifier as other than the first character.
@@ -69,6 +91,7 @@ public inline fun Char.isJavaIdentifierStart(): Boolean = Character.isJavaIdenti
/**
* Determines whether a character is whitespace according to the Unicode standard.
* Returns `true` if the character is whitespace.
*
* @sample samples.text.Chars.isWhitespace
*/
public actual fun Char.isWhitespace(): Boolean = Character.isWhitespace(this) || Character.isSpaceChar(this)
@@ -78,14 +101,14 @@ public actual fun Char.isWhitespace(): Boolean = Character.isWhitespace(this) ||
* @sample samples.text.Chars.isUpperCase
*/
@kotlin.internal.InlineOnly
public inline fun Char.isUpperCase(): Boolean = Character.isUpperCase(this)
public actual inline fun Char.isUpperCase(): Boolean = Character.isUpperCase(this)
/**
* Returns `true` if this character is lower case.
* @sample samples.text.Chars.isLowerCase
*/
@kotlin.internal.InlineOnly
public inline fun Char.isLowerCase(): Boolean = Character.isLowerCase(this)
public actual inline fun Char.isLowerCase(): Boolean = Character.isLowerCase(this)
/**
* Converts this character to lower case using Unicode mapping rules of the invariant locale.
@@ -192,7 +215,7 @@ public fun Char.lowercase(locale: Locale): String = toString().lowercase(locale)
* @sample samples.text.Chars.isTitleCase
*/
@kotlin.internal.InlineOnly
public inline fun Char.isTitleCase(): Boolean = Character.isTitleCase(this)
public actual inline fun Char.isTitleCase(): Boolean = Character.isTitleCase(this)
/**
* Converts this character to title case using Unicode mapping rules of the invariant locale.
@@ -260,11 +283,6 @@ public fun Char.titlecase(locale: Locale): String {
return titlecaseChar().toString()
}
/**
* Returns a value indicating a character's general category.
*/
public val Char.category: CharCategory get() = CharCategory.valueOf(Character.getType(this))
/**
* Returns the Unicode directionality property for the given character.
*/
+85
View File
@@ -227,3 +227,88 @@ public fun Char.equals(other: Char, ignoreCase: Boolean = false): Boolean {
* Returns `true` if this character is a Unicode surrogate code unit.
*/
public fun Char.isSurrogate(): Boolean = this in Char.MIN_SURROGATE..Char.MAX_SURROGATE
/**
* Returns the Unicode general category of this character.
*/
public expect val Char.category: CharCategory
/**
* Returns `true` if this character (Unicode code point) is defined in Unicode.
*
* A character is considered to be defined in Unicode if its [category] is not [CharCategory.UNASSIGNED].
*/
public expect fun Char.isDefined(): Boolean
/**
* Returns `true` if this character is a letter.
*
* A character is considered to be a letter if its [category] is [CharCategory.UPPERCASE_LETTER],
* [CharCategory.LOWERCASE_LETTER], [CharCategory.TITLECASE_LETTER], [CharCategory.MODIFIER_LETTER], or [CharCategory.OTHER_LETTER].
*
* @sample samples.text.Chars.isLetter
*/
public expect fun Char.isLetter(): Boolean
/**
* Returns `true` if this character is a letter or digit.
*
* @see isLetter
* @see isDigit
*
* @sample samples.text.Chars.isLetterOrDigit
*/
public expect fun Char.isLetterOrDigit(): Boolean
/**
* Returns `true` if this character is a digit.
*
* A character is considered to be a digit if its [category] is [CharCategory.DECIMAL_DIGIT_NUMBER].
*
* @sample samples.text.Chars.isDigit
*/
public expect fun Char.isDigit(): Boolean
/**
* Returns `true` if this character is an upper case letter.
*
* A character is considered to be an upper case letter if its [category] is [CharCategory.UPPERCASE_LETTER].
*
* @sample samples.text.Chars.isUpperCase
*/
public expect fun Char.isUpperCase(): Boolean
/**
* Returns `true` if this character is a lower case letter.
*
* A character is considered to be a lower case letter if its [category] is [CharCategory.LOWERCASE_LETTER].
*
* @sample samples.text.Chars.isLowerCase
*/
public expect fun Char.isLowerCase(): Boolean
/**
* Returns `true` if this character is a title case letter.
*
* A character is considered to be a title case letter if its [category] is [CharCategory.TITLECASE_LETTER].
*
* @sample samples.text.Chars.isTitleCase
*/
public expect fun Char.isTitleCase(): Boolean
/**
* Returns `true` if this character is an ISO control character.
*
* A character is considered to be an ISO control character if its [category] is [CharCategory.CONTROL].
*
* @sample samples.text.Chars.isISOControl
*/
public expect fun Char.isISOControl(): Boolean
/**
* Determines whether a character is whitespace according to the Unicode standard.
* Returns `true` if the character is whitespace.
*
* @sample samples.text.Chars.isWhitespace
*/
public expect fun Char.isWhitespace(): Boolean
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -8,166 +8,164 @@ package kotlin.text
/**
* Represents the character general category in the Unicode specification.
*/
public enum class CharCategory(public val value: Int, public val code: String) {
public expect enum class CharCategory {
/**
* General category "Cn" in the Unicode specification.
*/
UNASSIGNED(Character.UNASSIGNED.toInt(), "Cn"),
UNASSIGNED,
/**
* General category "Lu" in the Unicode specification.
*/
UPPERCASE_LETTER(Character.UPPERCASE_LETTER.toInt(), "Lu"),
UPPERCASE_LETTER,
/**
* General category "Ll" in the Unicode specification.
*/
LOWERCASE_LETTER(Character.LOWERCASE_LETTER.toInt(), "Ll"),
LOWERCASE_LETTER,
/**
* General category "Lt" in the Unicode specification.
*/
TITLECASE_LETTER(Character.TITLECASE_LETTER.toInt(), "Lt"),
TITLECASE_LETTER,
/**
* General category "Lm" in the Unicode specification.
*/
MODIFIER_LETTER(Character.MODIFIER_LETTER.toInt(), "Lm"),
MODIFIER_LETTER,
/**
* General category "Lo" in the Unicode specification.
*/
OTHER_LETTER(Character.OTHER_LETTER.toInt(), "Lo"),
OTHER_LETTER,
/**
* General category "Mn" in the Unicode specification.
*/
NON_SPACING_MARK(Character.NON_SPACING_MARK.toInt(), "Mn"),
NON_SPACING_MARK,
/**
* General category "Me" in the Unicode specification.
*/
ENCLOSING_MARK(Character.ENCLOSING_MARK.toInt(), "Me"),
ENCLOSING_MARK,
/**
* General category "Mc" in the Unicode specification.
*/
COMBINING_SPACING_MARK(Character.COMBINING_SPACING_MARK.toInt(), "Mc"),
COMBINING_SPACING_MARK,
/**
* General category "Nd" in the Unicode specification.
*/
DECIMAL_DIGIT_NUMBER(Character.DECIMAL_DIGIT_NUMBER.toInt(), "Nd"),
DECIMAL_DIGIT_NUMBER,
/**
* General category "Nl" in the Unicode specification.
*/
LETTER_NUMBER(Character.LETTER_NUMBER.toInt(), "Nl"),
LETTER_NUMBER,
/**
* General category "No" in the Unicode specification.
*/
OTHER_NUMBER(Character.OTHER_NUMBER.toInt(), "No"),
OTHER_NUMBER,
/**
* General category "Zs" in the Unicode specification.
*/
SPACE_SEPARATOR(Character.SPACE_SEPARATOR.toInt(), "Zs"),
SPACE_SEPARATOR,
/**
* General category "Zl" in the Unicode specification.
*/
LINE_SEPARATOR(Character.LINE_SEPARATOR.toInt(), "Zl"),
LINE_SEPARATOR,
/**
* General category "Zp" in the Unicode specification.
*/
PARAGRAPH_SEPARATOR(Character.PARAGRAPH_SEPARATOR.toInt(), "Zp"),
PARAGRAPH_SEPARATOR,
/**
* General category "Cc" in the Unicode specification.
*/
CONTROL(Character.CONTROL.toInt(), "Cc"),
CONTROL,
/**
* General category "Cf" in the Unicode specification.
*/
FORMAT(Character.FORMAT.toInt(), "Cf"),
FORMAT,
/**
* General category "Co" in the Unicode specification.
*/
PRIVATE_USE(Character.PRIVATE_USE.toInt(), "Co"),
PRIVATE_USE,
/**
* General category "Cs" in the Unicode specification.
*/
SURROGATE(Character.SURROGATE.toInt(), "Cs"),
SURROGATE,
/**
* General category "Pd" in the Unicode specification.
*/
DASH_PUNCTUATION(Character.DASH_PUNCTUATION.toInt(), "Pd"),
DASH_PUNCTUATION,
/**
* General category "Ps" in the Unicode specification.
*/
START_PUNCTUATION(Character.START_PUNCTUATION.toInt(), "Ps"),
START_PUNCTUATION,
/**
* General category "Pe" in the Unicode specification.
*/
END_PUNCTUATION(Character.END_PUNCTUATION.toInt(), "Pe"),
END_PUNCTUATION,
/**
* General category "Pc" in the Unicode specification.
*/
CONNECTOR_PUNCTUATION(Character.CONNECTOR_PUNCTUATION.toInt(), "Pc"),
CONNECTOR_PUNCTUATION,
/**
* General category "Po" in the Unicode specification.
*/
OTHER_PUNCTUATION(Character.OTHER_PUNCTUATION.toInt(), "Po"),
OTHER_PUNCTUATION,
/**
* General category "Sm" in the Unicode specification.
*/
MATH_SYMBOL(Character.MATH_SYMBOL.toInt(), "Sm"),
MATH_SYMBOL,
/**
* General category "Sc" in the Unicode specification.
*/
CURRENCY_SYMBOL(Character.CURRENCY_SYMBOL.toInt(), "Sc"),
CURRENCY_SYMBOL,
/**
* General category "Sk" in the Unicode specification.
*/
MODIFIER_SYMBOL(Character.MODIFIER_SYMBOL.toInt(), "Sk"),
MODIFIER_SYMBOL,
/**
* General category "So" in the Unicode specification.
*/
OTHER_SYMBOL(Character.OTHER_SYMBOL.toInt(), "So"),
OTHER_SYMBOL,
/**
* General category "Pi" in the Unicode specification.
*/
INITIAL_QUOTE_PUNCTUATION(Character.INITIAL_QUOTE_PUNCTUATION.toInt(), "Pi"),
INITIAL_QUOTE_PUNCTUATION,
/**
* General category "Pf" in the Unicode specification.
*/
FINAL_QUOTE_PUNCTUATION(Character.FINAL_QUOTE_PUNCTUATION.toInt(), "Pf");
FINAL_QUOTE_PUNCTUATION;
/**
* Two-letter code of this general category in the Unicode specification.
*/
public val code: String
/**
* Returns `true` if [char] character belongs to this category.
*/
public operator fun contains(char: Char): Boolean = Character.getType(char) == this.value
public companion object {
private val categoryMap by lazy { CharCategory.values().associateBy { it.value } }
public fun valueOf(category: Int): CharCategory = categoryMap[category] ?: throw IllegalArgumentException("Category #$category is not defined.")
}
public operator fun contains(char: Char): Boolean
}
+155
View File
@@ -7,6 +7,8 @@ package test.text
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import kotlin.test.assertFails
class CharTest {
@@ -146,4 +148,157 @@ class CharTest {
testFails(100, radix = 36)
testFails(100, radix = 110)
}
private fun charToCategory() = mapOf(
'\u0378' to "Cn",
'A' to "Lu", // \u0041
'a' to "Ll", // \u0061
'Dž' to "Lt", // \u01C5
'ʰ' to "Lm", // \u02B0
'ƻ' to "Lo", // \u01BB
'\u0300' to "Mn",
'\u0489' to "Me",
'\u0903' to "Mc",
'0' to "Nd", // \u0030
'' to "Nl", // \u2160
'²' to "No", // \u00B2
' ' to "Zs", // \u0020
'\u2028' to "Zl",
'\u2029' to "Zp",
'\u0018' to "Cc",
'\u00AD' to "Cf",
'\uE000' to "Co",
'\uD800' to "Cs",
'\u002D' to "Pd",
'(' to "Ps", // \u0028
')' to "Pe", // \u0029
'_' to "Pc", // \u005F
'!' to "Po", // \u0021
'+' to "Sm", // \u002B
'$' to "Sc", // \u0024
'^' to "Sk", // \u005E
'©' to "So", // \u00A9
'«' to "Pi", // \u00AB
'»' to "Pf" // \u00BB
)
@Test
fun charCategory() {
for ((char, categoryCode) in charToCategory()) {
assertEquals(categoryCode, char.category.code, "char code: ${char.toInt().toString(radix = 16)}")
}
}
@Test
fun charCategoryUnassigned() {
val unassignedChar = '\u0378'
assertFalse(unassignedChar.isDefined())
assertEquals(CharCategory.UNASSIGNED, unassignedChar.category)
assertEquals("Cn", CharCategory.UNASSIGNED.code)
}
@Test
fun charCategoryUppercaseLetter() {
val latinCapitalLetterA = 'A' // \u0041
assertTrue(latinCapitalLetterA.isLetterOrDigit())
assertTrue(latinCapitalLetterA.isLetter())
assertTrue(latinCapitalLetterA.isUpperCase())
assertEquals(CharCategory.UPPERCASE_LETTER, latinCapitalLetterA.category)
assertEquals("Lu", CharCategory.UPPERCASE_LETTER.code)
}
@Test
fun charCategoryLowercaseLetter() {
val latinSmallLetterA = 'a' // \u0061
assertTrue(latinSmallLetterA.isLetterOrDigit())
assertTrue(latinSmallLetterA.isLetter())
assertTrue(latinSmallLetterA.isLowerCase())
assertEquals(CharCategory.LOWERCASE_LETTER, latinSmallLetterA.category)
assertEquals("Ll", CharCategory.LOWERCASE_LETTER.code)
}
@Test
fun charCategoryTitlecaseLetter() {
val latinCapitalLetterDz = 'Dž' // \u01C5
assertTrue(latinCapitalLetterDz.isLetterOrDigit())
assertTrue(latinCapitalLetterDz.isLetter())
assertTrue(latinCapitalLetterDz.isTitleCase())
assertEquals(CharCategory.TITLECASE_LETTER, latinCapitalLetterDz.category)
assertEquals("Lt", CharCategory.TITLECASE_LETTER.code)
}
@Test
fun charCategoryModifierLetter() {
val modifierLetterSmallH = 'ʰ' // \u02B0
assertTrue(modifierLetterSmallH.isLetterOrDigit())
assertTrue(modifierLetterSmallH.isLetter())
assertEquals(CharCategory.MODIFIER_LETTER, modifierLetterSmallH.category)
assertEquals("Lm", CharCategory.MODIFIER_LETTER.code)
}
@Test
fun charCategoryOtherLetter() {
val twoWithStroke = 'ƻ' // \u01BB
assertTrue(twoWithStroke.isLetterOrDigit())
assertTrue(twoWithStroke.isLetter())
assertEquals(CharCategory.OTHER_LETTER, twoWithStroke.category)
assertEquals("Lo", CharCategory.OTHER_LETTER.code)
}
@Test
fun charCategoryDecimalDigitNumber() {
val digitZero = '0' // \u0030
assertTrue(digitZero.isLetterOrDigit())
assertTrue(digitZero.isDigit())
assertEquals(CharCategory.DECIMAL_DIGIT_NUMBER, digitZero.category)
assertEquals("Nd", CharCategory.DECIMAL_DIGIT_NUMBER.code)
}
@Test
fun charCategoryLetterNumber() {
val romanNumberOne = '' // \u2160
assertFalse(romanNumberOne.isDigit())
assertEquals(CharCategory.LETTER_NUMBER, romanNumberOne.category)
assertEquals("Nl", CharCategory.LETTER_NUMBER.code)
}
@Test
fun charCategoryOtherNumber() {
val superscriptTwo = '²' // \u00B2
assertFalse(superscriptTwo.isDigit())
assertEquals(CharCategory.OTHER_NUMBER, superscriptTwo.category)
assertEquals("No", CharCategory.OTHER_NUMBER.code)
}
@Test
fun charCategorySpaceSeparator() {
val superscriptTwo = ' ' // \u0020
assertTrue(superscriptTwo.isWhitespace())
assertEquals(CharCategory.SPACE_SEPARATOR, superscriptTwo.category)
assertEquals("Zs", CharCategory.SPACE_SEPARATOR.code)
}
@Test
fun charCategoryLineSeparator() {
val lineSeparator = '\u2028'
assertTrue(lineSeparator.isWhitespace())
assertEquals(CharCategory.LINE_SEPARATOR, lineSeparator.category)
assertEquals("Zl", CharCategory.LINE_SEPARATOR.code)
}
@Test
fun charCategoryParagraphSeparator() {
val paragraphSeparator = '\u2029'
assertTrue(paragraphSeparator.isWhitespace())
assertEquals(CharCategory.PARAGRAPH_SEPARATOR, paragraphSeparator.category)
assertEquals("Zp", CharCategory.PARAGRAPH_SEPARATOR.code)
}
@Test
fun charCategoryControl() {
val controlCancel = '\u0018'
assertTrue(controlCancel.isISOControl())
assertEquals(CharCategory.CONTROL, controlCancel.category)
assertEquals("Cc", CharCategory.CONTROL.code)
}
}
+86 -1
View File
@@ -63,7 +63,6 @@ actual enum class RegexOption {
// From char.kt
actual fun Char.isWhitespace(): Boolean = TODO("Wasm stdlib: Text")
actual fun Char.isHighSurrogate(): Boolean = TODO("Wasm stdlib: Text")
actual fun Char.isLowSurrogate(): Boolean = TODO("Wasm stdlib: Text")
@@ -131,6 +130,92 @@ public actual fun Char.uppercaseChar(): Char = TODO("Wasm stdlib: Text")
@ExperimentalStdlibApi
public actual fun Char.uppercase(): String = TODO("Wasm stdlib: Text")
/**
* Returns the Unicode general category of this character.
*/
public actual val Char.category: CharCategory get() = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character (Unicode code point) is defined in Unicode.
*
* A character is considered to be defined in Unicode if its [category] is not [CharCategory.UNASSIGNED].
*/
public actual fun Char.isDefined(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is a letter.
*
* A character is considered to be a letter if its [category] is [CharCategory.UPPERCASE_LETTER],
* [CharCategory.LOWERCASE_LETTER], [CharCategory.TITLECASE_LETTER], [CharCategory.MODIFIER_LETTER], or [CharCategory.OTHER_LETTER].
*
* @sample samples.text.Chars.isLetter
*/
public actual fun Char.isLetter(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is a letter or digit.
*
* @see isLetter
* @see isDigit
*
* @sample samples.text.Chars.isLetterOrDigit
*/
public actual fun Char.isLetterOrDigit(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is a digit.
*
* A character is considered to be a digit if its [category] is [CharCategory.DECIMAL_DIGIT_NUMBER].
*
* @sample samples.text.Chars.isDigit
*/
public actual fun Char.isDigit(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is an upper case letter.
*
* A character is considered to be an upper case letter if its [category] is [CharCategory.UPPERCASE_LETTER].
*
* @sample samples.text.Chars.isUpperCase
*/
public actual fun Char.isUpperCase(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is a lower case letter.
*
* A character is considered to be a lower case letter if its [category] is [CharCategory.LOWERCASE_LETTER].
*
* @sample samples.text.Chars.isLowerCase
*/
public actual fun Char.isLowerCase(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is a title case letter.
*
* A character is considered to be a title case letter if its [category] is [CharCategory.TITLECASE_LETTER].
*
* @sample samples.text.Chars.isTitleCase
*/
public actual fun Char.isTitleCase(): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if this character is an ISO control character.
*
* A character is considered to be an ISO control character if its [category] is [CharCategory.CONTROL].
*
* @sample samples.text.Chars.isISOControl
*/
public actual fun Char.isISOControl(): Boolean = TODO("Wasm stdlib: Text")
/**
* Determines whether a character is whitespace according to the Unicode standard.
* Returns `true` if the character is whitespace.
*
* @sample samples.text.Chars.isWhitespace
*/
public actual fun Char.isWhitespace(): Boolean = TODO("Wasm stdlib: Text")
// From string.kt
@@ -0,0 +1,171 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.text
/**
* Represents the character general category in the Unicode specification.
*/
public actual enum class CharCategory {
/**
* General category "Cn" in the Unicode specification.
*/
UNASSIGNED,
/**
* General category "Lu" in the Unicode specification.
*/
UPPERCASE_LETTER,
/**
* General category "Ll" in the Unicode specification.
*/
LOWERCASE_LETTER,
/**
* General category "Lt" in the Unicode specification.
*/
TITLECASE_LETTER,
/**
* General category "Lm" in the Unicode specification.
*/
MODIFIER_LETTER,
/**
* General category "Lo" in the Unicode specification.
*/
OTHER_LETTER,
/**
* General category "Mn" in the Unicode specification.
*/
NON_SPACING_MARK,
/**
* General category "Me" in the Unicode specification.
*/
ENCLOSING_MARK,
/**
* General category "Mc" in the Unicode specification.
*/
COMBINING_SPACING_MARK,
/**
* General category "Nd" in the Unicode specification.
*/
DECIMAL_DIGIT_NUMBER,
/**
* General category "Nl" in the Unicode specification.
*/
LETTER_NUMBER,
/**
* General category "No" in the Unicode specification.
*/
OTHER_NUMBER,
/**
* General category "Zs" in the Unicode specification.
*/
SPACE_SEPARATOR,
/**
* General category "Zl" in the Unicode specification.
*/
LINE_SEPARATOR,
/**
* General category "Zp" in the Unicode specification.
*/
PARAGRAPH_SEPARATOR,
/**
* General category "Cc" in the Unicode specification.
*/
CONTROL,
/**
* General category "Cf" in the Unicode specification.
*/
FORMAT,
/**
* General category "Co" in the Unicode specification.
*/
PRIVATE_USE,
/**
* General category "Cs" in the Unicode specification.
*/
SURROGATE,
/**
* General category "Pd" in the Unicode specification.
*/
DASH_PUNCTUATION,
/**
* General category "Ps" in the Unicode specification.
*/
START_PUNCTUATION,
/**
* General category "Pe" in the Unicode specification.
*/
END_PUNCTUATION,
/**
* General category "Pc" in the Unicode specification.
*/
CONNECTOR_PUNCTUATION,
/**
* General category "Po" in the Unicode specification.
*/
OTHER_PUNCTUATION,
/**
* General category "Sm" in the Unicode specification.
*/
MATH_SYMBOL,
/**
* General category "Sc" in the Unicode specification.
*/
CURRENCY_SYMBOL,
/**
* General category "Sk" in the Unicode specification.
*/
MODIFIER_SYMBOL,
/**
* General category "So" in the Unicode specification.
*/
OTHER_SYMBOL,
/**
* General category "Pi" in the Unicode specification.
*/
INITIAL_QUOTE_PUNCTUATION,
/**
* General category "Pf" in the Unicode specification.
*/
FINAL_QUOTE_PUNCTUATION;
/**
* Two-letter code of this general category in the Unicode specification.
*/
public actual val code: String get() = TODO("Wasm stdlib: Text")
/**
* Returns `true` if [char] character belongs to this category.
*/
public actual operator fun contains(char: Char): Boolean = TODO("Wasm stdlib: Text")
}