From d55e16a0300f41843ba9c80a8d2f690623d48636 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Fri, 26 Nov 2021 15:23:40 +0100 Subject: [PATCH] [WASM] Regex std implementation --- .../kotlin/code/CodeConformanceTest.kt | 3 +- .../backend.native/tests/build.gradle | 2 +- kotlin-native/runtime/src/main/cpp/Regex.cpp | 6 +- .../src/main/kotlin/kotlin/text/CharNative.kt | 59 + .../kotlin/text/regex/DecompositionHelpers.kt | 36 + .../src}/kotlin/text/Appendable.kt | 0 .../native-wasm/src}/kotlin/text/Char.kt | 54 +- .../src}/kotlin/text/CharCategory.kt | 0 .../kotlin/text/PatternSyntaxException.kt | 0 .../native-wasm/src}/kotlin/text/Regex.kt | 0 .../kotlin/text/regex/AbstractCharClass.kt | 1 + .../text/regex/AbstractLineTerminator.kt | 0 .../src}/kotlin/text/regex/CharClass.kt | 2 + .../src}/kotlin/text/regex/Lexer.kt | 23 - .../src}/kotlin/text/regex/MatchResultImpl.kt | 0 .../src}/kotlin/text/regex/Pattern.kt | 0 .../src}/kotlin/text/regex/Quantifier.kt | 0 .../kotlin/text/regex/sets/AbstractSet.kt | 0 .../kotlin/text/regex/sets/AtomicJointSet.kt | 0 .../text/regex/sets/BackReferenceSet.kt | 0 .../src}/kotlin/text/regex/sets/CharSet.kt | 0 .../text/regex/sets/CompositeRangeSet.kt | 0 .../text/regex/sets/DecomposedCharSet.kt | 9 - .../text/regex/sets/DotQuantifierSet.kt | 0 .../src}/kotlin/text/regex/sets/DotSet.kt | 0 .../src}/kotlin/text/regex/sets/EOISet.kt | 0 .../src}/kotlin/text/regex/sets/EOLSet.kt | 0 .../src}/kotlin/text/regex/sets/EmptySet.kt | 0 .../src}/kotlin/text/regex/sets/FSets.kt | 0 .../text/regex/sets/GroupQuantifierSet.kt | 0 .../regex/sets/HangulDecomposedCharSet.kt | 0 .../src}/kotlin/text/regex/sets/JointSet.kt | 0 .../text/regex/sets/LeafQuantifierSet.kt | 0 .../src}/kotlin/text/regex/sets/LeafSet.kt | 0 .../kotlin/text/regex/sets/LookAheadSets.kt | 0 .../kotlin/text/regex/sets/LookAroundSet.kt | 0 .../kotlin/text/regex/sets/LookBehindSets.kt | 0 .../text/regex/sets/NonCapturingJointSet.kt | 0 .../sets/PossessiveGroupQuantifierSet.kt | 0 .../regex/sets/PossessiveLeafQuantifierSet.kt | 0 .../text/regex/sets/PreviousMatchSet.kt | 0 .../kotlin/text/regex/sets/QuantifierSet.kt | 0 .../src}/kotlin/text/regex/sets/RangeSet.kt | 0 .../regex/sets/ReluctantGroupQuantifierSet.kt | 0 .../regex/sets/ReluctantLeafQuantifierSet.kt | 0 .../src}/kotlin/text/regex/sets/SOLSet.kt | 0 .../kotlin/text/regex/sets/SequenceSet.kt | 0 .../src}/kotlin/text/regex/sets/SingleSet.kt | 0 .../text/regex/sets/SupplementaryCharSet.kt | 0 .../text/regex/sets/SupplementaryRangeSet.kt | 0 .../text/regex/sets/SurrogateCharSets.kt | 0 .../text/regex/sets/SurrogateRangeSet.kt | 0 .../text/regex/sets/UnifiedQuantifierSet.kt | 0 .../kotlin/text/regex/sets/WordBoundarySet.kt | 0 .../test}/harmony_regex/AllCodePointsTest.kt | 0 .../test}/harmony_regex/FindAllTest.kt | 0 .../test}/harmony_regex/MatchResultTest.kt | 0 .../test}/harmony_regex/MatchResultTest2.kt | 0 .../test}/harmony_regex/ModeTest.kt | 0 .../test}/harmony_regex/PatternErrorTest.kt | 0 .../PatternSyntaxExceptionTest.kt | 0 .../test}/harmony_regex/PatternTest.kt | 0 .../test}/harmony_regex/PatternTest2.kt | 0 .../test}/harmony_regex/ReplaceTest.kt | 0 .../test}/harmony_regex/SplitTest.kt | 0 libraries/stdlib/wasm/build.gradle.kts | 3 +- libraries/stdlib/wasm/builtins/kotlin/Char.kt | 16 +- libraries/stdlib/wasm/src/kotlin/Text.kt | 972 -------- .../stdlib/wasm/src/kotlin/text/Appendable.kt | 37 - .../wasm/src/kotlin/text/CharCategoryWasm.kt | 176 -- .../stdlib/wasm/src/kotlin/text/CharWasm.kt | 33 +- .../text/StringNumberConversionsWasm.kt | 162 ++ .../wasm/src/kotlin/text/StringsWasm.kt | 457 +++- .../wasm/src/kotlin/text/regex/BitSet.kt | 257 +++ .../kotlin/text/regex/DecompositionHelpers.kt | 318 +++ .../kotlin/text/regex/DecompositionValues.kt | 2041 +++++++++++++++++ .../stdlib/wasm/stubs/native/concurrent.kt | 20 + libraries/stdlib/wasm/test/testUtils.kt | 2 +- 78 files changed, 3403 insertions(+), 1286 deletions(-) create mode 100644 kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt create mode 100644 kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/Appendable.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/Char.kt (83%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/CharCategory.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/PatternSyntaxException.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/Regex.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/AbstractCharClass.kt (99%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/AbstractLineTerminator.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/CharClass.kt (99%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/Lexer.kt (96%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/MatchResultImpl.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/Pattern.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/Quantifier.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/AbstractSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/AtomicJointSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/BackReferenceSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/CharSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/CompositeRangeSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/DecomposedCharSet.kt (94%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/DotQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/DotSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/EOISet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/EOLSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/EmptySet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/FSets.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/GroupQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/HangulDecomposedCharSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/JointSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/LeafQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/LeafSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/LookAheadSets.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/LookAroundSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/LookBehindSets.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/NonCapturingJointSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/PossessiveGroupQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/PossessiveLeafQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/PreviousMatchSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/QuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/RangeSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/ReluctantGroupQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/ReluctantLeafQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SOLSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SequenceSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SingleSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SupplementaryCharSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SupplementaryRangeSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SurrogateCharSets.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/SurrogateRangeSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/UnifiedQuantifierSet.kt (100%) rename {kotlin-native/runtime/src/main/kotlin => libraries/stdlib/native-wasm/src}/kotlin/text/regex/sets/WordBoundarySet.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/AllCodePointsTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/FindAllTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/MatchResultTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/MatchResultTest2.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/ModeTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/PatternErrorTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/PatternSyntaxExceptionTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/PatternTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/PatternTest2.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/ReplaceTest.kt (100%) rename {kotlin-native/backend.native/tests => libraries/stdlib/native-wasm/test}/harmony_regex/SplitTest.kt (100%) delete mode 100644 libraries/stdlib/wasm/src/kotlin/Text.kt delete mode 100644 libraries/stdlib/wasm/src/kotlin/text/Appendable.kt delete mode 100644 libraries/stdlib/wasm/src/kotlin/text/CharCategoryWasm.kt create mode 100644 libraries/stdlib/wasm/src/kotlin/text/StringNumberConversionsWasm.kt create mode 100644 libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt create mode 100644 libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt create mode 100644 libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionValues.kt diff --git a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt index ab202461799..1f76b2522ec 100644 --- a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt @@ -113,9 +113,8 @@ class CodeConformanceTest : TestCase() { "libraries/tools/kotlin-test-nodejs-runner/.gradle", "libraries/tools/kotlin-test-nodejs-runner/node_modules", "libraries/tools/kotlin-source-map-loader/.gradle", - "kotlin-native", // Have a separate licences manager + "kotlin-native", "libraries/stdlib/native-wasm", // Have a separate licences manager "out", - "kotlin-native/runtime" ) ) } diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index 85327e13037..05e43f862b8 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -5632,7 +5632,7 @@ KotlinNativeTestKt.createTest(project, 'harmonyRegexTest', KonanGTest) { task -> task.useFilter = false task.testLogger = KonanTest.Logger.GTEST - def sources = UtilsKt.getFilesToCompile(project, ["harmony_regex"], []) + def sources = UtilsKt.getFilesToCompile(project, ["../../../libraries/stdlib/native-wasm/test/harmony_regex"], []) konanArtifacts { program('harmonyRegexTest', targets: [target.name]) { diff --git a/kotlin-native/runtime/src/main/cpp/Regex.cpp b/kotlin-native/runtime/src/main/cpp/Regex.cpp index b8371d7ed0a..10edac65934 100644 --- a/kotlin-native/runtime/src/main/cpp/Regex.cpp +++ b/kotlin-native/runtime/src/main/cpp/Regex.cpp @@ -542,7 +542,7 @@ constexpr Decomposition decompositionValues[] = { KInt getCanonicalClass(KInt ch) { int index = binarySearchRange(canonicalClassesKeys, ARRAY_SIZE(canonicalClassesKeys), ch); - if (canonicalClassesKeys[index] != ch) { + if (index == -1 || canonicalClassesKeys[index] != ch) { return 0; } return canonicalClassesValues[index]; @@ -550,7 +550,7 @@ KInt getCanonicalClass(KInt ch) { const Decomposition* getDecomposition(KInt codePoint) { int index = binarySearchRange(decompositionKeys, ARRAY_SIZE(decompositionKeys), codePoint); - if (decompositionKeys[index] != codePoint) { + if (index == -1 || decompositionKeys[index] != codePoint) { return nullptr; } return &decompositionValues[index]; @@ -566,7 +566,7 @@ KInt Kotlin_text_regex_getCanonicalClassInternal(KInt ch) { KBoolean Kotlin_text_regex_hasSingleCodepointDecompositionInternal(KInt ch) { int index = binarySearchRange(singleDecompositions, ARRAY_SIZE(singleDecompositions), ch); - return singleDecompositions[index] == ch; + return index != -1 && singleDecompositions[index] == ch; } OBJ_GETTER(Kotlin_text_regex_getDecompositionInternal, KInt ch) { diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt new file mode 100644 index 00000000000..a26526ba7a6 --- /dev/null +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt @@ -0,0 +1,59 @@ +/* + * 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 + +import kotlin.native.internal.GCUnsafeCall + +/** + * Returns `true` if this character is a Unicode high-surrogate code unit (also known as leading-surrogate code unit). + */ +@GCUnsafeCall("Kotlin_Char_isHighSurrogate") +external public actual fun Char.isHighSurrogate(): Boolean + +/** + * Returns `true` if this character is a Unicode low-surrogate code unit (also known as trailing-surrogate code unit). + */ +@GCUnsafeCall("Kotlin_Char_isLowSurrogate") +external public actual fun Char.isLowSurrogate(): Boolean + +/** + * Returns `true` if this character (Unicode code point) should be regarded as an ignorable + * character in a Java identifier or a Unicode identifier. + */ +@GCUnsafeCall("Kotlin_Char_isIdentifierIgnorable") +external public fun Char.isIdentifierIgnorable(): 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], + * meaning the Char is in the range `'\u0000'..'\u001F'` or in the range `'\u007F'..'\u009F'`. + * + * @sample samples.text.Chars.isISOControl + */ +@GCUnsafeCall("Kotlin_Char_isISOControl") +external public actual fun Char.isISOControl(): Boolean + +@SharedImmutable +private val digits = intArrayOf( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, + -1, -1, -1, -1, -1, -1, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35 +) + +internal actual fun digitOf(char: Char, radix: Int): Int = when { + char >= '0' && char <= 'z' -> digits[char - '0'] + char < '\u0080' -> -1 + char >= '\uFF21' && char <= '\uFF3A' -> char - '\uFF21' + 10 // full-width latin capital letter + char >= '\uFF41' && char <= '\uFF5A' -> char - '\uFF41' + 10 // full-width latin small letter + else -> char.digitToIntImpl() +}.let { if (it >= radix) -1 else it } \ No newline at end of file diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt new file mode 100644 index 00000000000..948acd519f9 --- /dev/null +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt @@ -0,0 +1,36 @@ +/* + * 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.regex + +import kotlin.native.internal.GCUnsafeCall + +// Access to the decomposition tables. ========================================================================= +/** Gets canonical class for given codepoint from decomposition mappings table. */ +@GCUnsafeCall("Kotlin_text_regex_getCanonicalClassInternal") +external internal fun getCanonicalClassInternal(ch: Int): Int + +/** Check if the given character is in table of single decompositions. */ +@GCUnsafeCall("Kotlin_text_regex_hasSingleCodepointDecompositionInternal") +external internal fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean + +/** Returns a decomposition for a given codepoint. */ +@GCUnsafeCall("Kotlin_text_regex_getDecompositionInternal") +external internal fun getDecompositionInternal(ch: Int): IntArray? + +/** + * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. + * Returns the length of the decomposition. + */ +@GCUnsafeCall("Kotlin_text_regex_decomposeString") +external internal fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int + +/** + * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. + * Returns the length of the decomposition. + */ +@GCUnsafeCall("Kotlin_text_regex_decomposeCodePoint") +external internal fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int +// ============================================================================================================= \ No newline at end of file diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/Appendable.kt b/libraries/stdlib/native-wasm/src/kotlin/text/Appendable.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/Appendable.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/Appendable.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/Char.kt b/libraries/stdlib/native-wasm/src/kotlin/text/Char.kt similarity index 83% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/Char.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/Char.kt index 103078a8b04..e966a7e2d02 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/Char.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/Char.kt @@ -6,7 +6,6 @@ package kotlin.text import kotlin.IllegalArgumentException -import kotlin.native.internal.GCUnsafeCall /** * Returns `true` if this character (Unicode code point) is defined in Unicode. @@ -74,24 +73,6 @@ public actual fun Char.isDigit(): Boolean { return isDigitImpl() } -/** - * Returns `true` if this character (Unicode code point) should be regarded as an ignorable - * character in a Java identifier or a Unicode identifier. - */ -@GCUnsafeCall("Kotlin_Char_isIdentifierIgnorable") -external public fun Char.isIdentifierIgnorable(): 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], - * meaning the Char is in the range `'\u0000'..'\u001F'` or in the range `'\u007F'..'\u009F'`. - * - * @sample samples.text.Chars.isISOControl - */ -@GCUnsafeCall("Kotlin_Char_isISOControl") -external public actual fun Char.isISOControl(): Boolean - /** * Determines whether a character is whitespace according to the Unicode standard. * Returns `true` if the character is whitespace. @@ -231,39 +212,6 @@ public actual fun Char.lowercase(): String = lowercaseImpl() @SinceKotlin("1.5") public actual fun Char.titlecaseChar(): Char = titlecaseCharImpl() -/** - * Returns `true` if this character is a Unicode high-surrogate code unit (also known as leading-surrogate code unit). - */ -@GCUnsafeCall("Kotlin_Char_isHighSurrogate") -external public actual fun Char.isHighSurrogate(): Boolean - -/** - * Returns `true` if this character is a Unicode low-surrogate code unit (also known as trailing-surrogate code unit). - */ -@GCUnsafeCall("Kotlin_Char_isLowSurrogate") -external public actual fun Char.isLowSurrogate(): Boolean - -@SharedImmutable -private val digits = intArrayOf( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - -1, -1, -1, -1, -1, -1, -1, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, - -1, -1, -1, -1, -1, -1, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35 -) - -internal actual fun digitOf(char: Char, radix: Int): Int = when { - char >= '0' && char <= 'z' -> digits[char - '0'] - char < '\u0080' -> -1 - char >= '\uFF21' && char <= '\uFF3A' -> char - '\uFF21' + 10 // full-width latin capital letter - char >= '\uFF41' && char <= '\uFF5A' -> char - '\uFF41' + 10 // full-width latin small letter - else -> char.digitToIntImpl() -}.let { if (it >= radix) -1 else it } - /** * Returns the Unicode general category of this character. */ @@ -331,4 +279,4 @@ public fun Char.Companion.toChars(codePoint: Int): CharArray = charArrayOf(high.toChar(), low.toChar()) } else -> throw IllegalArgumentException() - } + } \ No newline at end of file diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharCategory.kt b/libraries/stdlib/native-wasm/src/kotlin/text/CharCategory.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/CharCategory.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/CharCategory.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/PatternSyntaxException.kt b/libraries/stdlib/native-wasm/src/kotlin/text/PatternSyntaxException.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/PatternSyntaxException.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/PatternSyntaxException.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/Regex.kt b/libraries/stdlib/native-wasm/src/kotlin/text/Regex.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/Regex.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/Regex.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt similarity index 99% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt index 9f361ceb5d6..090a5e4394c 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/AbstractCharClass.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt @@ -26,6 +26,7 @@ package kotlin.text.regex import kotlin.collections.associate import kotlin.native.concurrent.AtomicReference import kotlin.native.concurrent.freeze +import kotlin.native.BitSet /** * Unicode category (i.e. Ll, Lu). diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/AbstractLineTerminator.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractLineTerminator.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/AbstractLineTerminator.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractLineTerminator.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/CharClass.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt similarity index 99% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/CharClass.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt index ed16b6ee623..9333d9423d0 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/CharClass.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt @@ -22,6 +22,8 @@ @file:Suppress("DEPRECATION") // Char.toInt() package kotlin.text.regex +import kotlin.native.BitSet + /** * User defined character classes (e.g. [abef]). */ diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Lexer.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/Lexer.kt similarity index 96% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Lexer.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/Lexer.kt index 364c21eb3d6..76a9f6e8eab 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Lexer.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/Lexer.kt @@ -24,29 +24,6 @@ @file:Suppress("DEPRECATION") // Char.toInt() package kotlin.text.regex -import kotlin.native.internal.GCUnsafeCall - -// Access to the decomposition tables. ========================================================================= -/** Gets canonical class for given codepoint from decomposition mappings table. */ -@GCUnsafeCall("Kotlin_text_regex_getCanonicalClassInternal") -external private fun getCanonicalClassInternal(ch: Int): Int - -/** Check if the given character is in table of single decompositions. */ -@GCUnsafeCall("Kotlin_text_regex_hasSingleCodepointDecompositionInternal") -external private fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean - -/** Returns a decomposition for a given codepoint. */ -@GCUnsafeCall("Kotlin_text_regex_getDecompositionInternal") -external private fun getDecompositionInternal(ch: Int): IntArray? - -/** - * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. - * Returns the length of the decomposition. - */ -@GCUnsafeCall("Kotlin_text_regex_decomposeString") -external private fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int -// ============================================================================================================= - /** * This is base class for special tokens like character classes and quantifiers. */ diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/MatchResultImpl.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/MatchResultImpl.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/MatchResultImpl.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/MatchResultImpl.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Pattern.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/Pattern.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Pattern.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/Pattern.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Quantifier.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/Quantifier.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/Quantifier.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/Quantifier.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/AbstractSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/AbstractSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/AbstractSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/AbstractSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/AtomicJointSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/AtomicJointSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/AtomicJointSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/AtomicJointSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/BackReferenceSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/BackReferenceSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/BackReferenceSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/BackReferenceSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/CharSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/CharSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/CharSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/CharSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/CompositeRangeSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/CompositeRangeSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/CompositeRangeSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/CompositeRangeSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DecomposedCharSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DecomposedCharSet.kt similarity index 94% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DecomposedCharSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DecomposedCharSet.kt index 5b7ff0cff2d..349729dd17a 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DecomposedCharSet.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DecomposedCharSet.kt @@ -22,15 +22,6 @@ package kotlin.text.regex -import kotlin.native.internal.GCUnsafeCall - -/** - * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. - * Returns the length of the decomposition. - */ -@GCUnsafeCall("Kotlin_text_regex_decomposeCodePoint") -external private fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int - /** Represents canonical decomposition of Unicode character. Is used when CANON_EQ flag of Pattern class is specified. */ open internal class DecomposedCharSet( /** Decomposition of the Unicode codepoint */ diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DotQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DotQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DotQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DotQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DotSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DotSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/DotSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/DotSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/EOISet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/EOISet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/EOISet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/EOISet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/EOLSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/EOLSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/EOLSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/EOLSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/EmptySet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/EmptySet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/EmptySet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/EmptySet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/FSets.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/FSets.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/FSets.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/FSets.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/GroupQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/GroupQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/GroupQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/GroupQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/HangulDecomposedCharSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/HangulDecomposedCharSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/HangulDecomposedCharSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/HangulDecomposedCharSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/JointSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/JointSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/JointSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/JointSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LeafQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LeafQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LeafQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LeafQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LeafSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LeafSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LeafSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LeafSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LookAheadSets.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LookAheadSets.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LookAheadSets.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LookAheadSets.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LookAroundSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LookAroundSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LookAroundSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LookAroundSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LookBehindSets.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LookBehindSets.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/LookBehindSets.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/LookBehindSets.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/NonCapturingJointSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/NonCapturingJointSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/NonCapturingJointSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/NonCapturingJointSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/PossessiveGroupQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/PossessiveGroupQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/PossessiveGroupQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/PossessiveGroupQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/PossessiveLeafQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/PossessiveLeafQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/PossessiveLeafQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/PossessiveLeafQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/PreviousMatchSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/PreviousMatchSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/PreviousMatchSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/PreviousMatchSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/QuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/QuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/QuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/QuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/RangeSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/RangeSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/RangeSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/RangeSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/ReluctantGroupQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/ReluctantGroupQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/ReluctantGroupQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/ReluctantGroupQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/ReluctantLeafQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/ReluctantLeafQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/ReluctantLeafQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/ReluctantLeafQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SOLSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SOLSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SOLSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SOLSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SequenceSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SequenceSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SequenceSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SequenceSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SingleSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SingleSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SingleSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SingleSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SupplementaryCharSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SupplementaryCharSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SupplementaryCharSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SupplementaryCharSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SupplementaryRangeSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SupplementaryRangeSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SupplementaryRangeSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SupplementaryRangeSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SurrogateCharSets.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SurrogateCharSets.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SurrogateCharSets.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SurrogateCharSets.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SurrogateRangeSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SurrogateRangeSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/SurrogateRangeSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/SurrogateRangeSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/UnifiedQuantifierSet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/UnifiedQuantifierSet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/UnifiedQuantifierSet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/UnifiedQuantifierSet.kt diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/WordBoundarySet.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/WordBoundarySet.kt similarity index 100% rename from kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/sets/WordBoundarySet.kt rename to libraries/stdlib/native-wasm/src/kotlin/text/regex/sets/WordBoundarySet.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/AllCodePointsTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/AllCodePointsTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/AllCodePointsTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/AllCodePointsTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/FindAllTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/FindAllTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/FindAllTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/FindAllTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/MatchResultTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/MatchResultTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/MatchResultTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/MatchResultTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/MatchResultTest2.kt b/libraries/stdlib/native-wasm/test/harmony_regex/MatchResultTest2.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/MatchResultTest2.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/MatchResultTest2.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/ModeTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/ModeTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/ModeTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/ModeTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/PatternErrorTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/PatternErrorTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/PatternErrorTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/PatternErrorTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/PatternSyntaxExceptionTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/PatternSyntaxExceptionTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/PatternSyntaxExceptionTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/PatternSyntaxExceptionTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/PatternTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/PatternTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/PatternTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/PatternTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/PatternTest2.kt b/libraries/stdlib/native-wasm/test/harmony_regex/PatternTest2.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/PatternTest2.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/PatternTest2.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/ReplaceTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/ReplaceTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/ReplaceTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/ReplaceTest.kt diff --git a/kotlin-native/backend.native/tests/harmony_regex/SplitTest.kt b/libraries/stdlib/native-wasm/test/harmony_regex/SplitTest.kt similarity index 100% rename from kotlin-native/backend.native/tests/harmony_regex/SplitTest.kt rename to libraries/stdlib/native-wasm/test/harmony_regex/SplitTest.kt diff --git a/libraries/stdlib/wasm/build.gradle.kts b/libraries/stdlib/wasm/build.gradle.kts index 3e317e084e2..4488bad00e7 100644 --- a/libraries/stdlib/wasm/build.gradle.kts +++ b/libraries/stdlib/wasm/build.gradle.kts @@ -82,7 +82,7 @@ kotlin { sourceSets { val wasmMain by getting { kotlin.srcDirs("builtins", "internal", "runtime", "src", "stubs") - kotlin.srcDirs("../native-wasm/") + kotlin.srcDirs("$rootDir/libraries/stdlib/native-wasm/src") kotlin.srcDirs(files(builtInsSources.map { it.destinationDir })) } @@ -102,6 +102,7 @@ kotlin { api(project(":kotlin-test:kotlin-test-wasm")) } kotlin.srcDir("$rootDir/libraries/stdlib/wasm/test/") + kotlin.srcDir("$rootDir/libraries/stdlib/native-wasm/test/") } } } diff --git a/libraries/stdlib/wasm/builtins/kotlin/Char.kt b/libraries/stdlib/wasm/builtins/kotlin/Char.kt index 3238aff24fc..3b8192f6b7b 100644 --- a/libraries/stdlib/wasm/builtins/kotlin/Char.kt +++ b/libraries/stdlib/wasm/builtins/kotlin/Char.kt @@ -144,17 +144,27 @@ public class Char private constructor(public val value: Char) : Comparable /** * The minimum value of a supplementary code point, `\u0x10000`. */ - public const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000 + internal const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000 + + /** + * The minimum value of a Unicode code point. + */ + internal const val MIN_CODE_POINT = 0x000000 + + /** + * The maximum value of a Unicode code point. + */ + internal const val MAX_CODE_POINT = 0X10FFFF /** * The minimum radix available for conversion to and from strings. */ - public const val MIN_RADIX: Int = 2 + internal const val MIN_RADIX: Int = 2 /** * The maximum radix available for conversion to and from strings. */ - public const val MAX_RADIX: Int = 36 + internal const val MAX_RADIX: Int = 36 /** * The number of bytes used to represent a Char in a binary form. diff --git a/libraries/stdlib/wasm/src/kotlin/Text.kt b/libraries/stdlib/wasm/src/kotlin/Text.kt deleted file mode 100644 index 4e6fc6a8a39..00000000000 --- a/libraries/stdlib/wasm/src/kotlin/Text.kt +++ /dev/null @@ -1,972 +0,0 @@ -/* - * 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 - -import kotlin.math.abs - -actual class Regex { - actual constructor(pattern: String) { TODO("Wasm stdlib: Text") } - actual constructor(pattern: String, option: RegexOption) { TODO("Wasm stdlib: Text") } - actual constructor(pattern: String, options: Set) { TODO("Wasm stdlib: Text") } - - actual val pattern: String = TODO("Wasm stdlib: Text") - actual val options: Set = TODO("Wasm stdlib: Text") - - actual fun matchEntire(input: CharSequence): MatchResult? = TODO("Wasm stdlib: Text") - actual infix fun matches(input: CharSequence): Boolean = TODO("Wasm stdlib: Text") - actual fun containsMatchIn(input: CharSequence): Boolean = TODO("Wasm stdlib: Text") - actual fun replace(input: CharSequence, replacement: String): String = TODO("Wasm stdlib: Text") - actual fun replace(input: CharSequence, transform: (MatchResult) -> CharSequence): String = TODO("Wasm stdlib: Text") - actual fun replaceFirst(input: CharSequence, replacement: String): String = TODO("Wasm stdlib: Text") - - actual fun matchAt(input: CharSequence, index: Int): MatchResult? = TODO("Wasm stdlib: Text") - actual fun matchesAt(input: CharSequence, index: Int): Boolean = TODO("Wasm stdlib: Text") - - /** - * Returns the first match of a regular expression in the [input], beginning at the specified [startIndex]. - * - * @param startIndex An index to start search with, by default 0. Must be not less than zero and not greater than `input.length()` - * @return An instance of [MatchResult] if match was found or `null` otherwise. - * @sample samples.text.Regexps.find - */ - actual fun find(input: CharSequence, startIndex: Int): MatchResult? = TODO("Wasm stdlib: Text") - - /** - * Returns a sequence of all occurrences of a regular expression within the [input] string, beginning at the specified [startIndex]. - * - * @sample samples.text.Regexps.findAll - */ - actual fun findAll(input: CharSequence, startIndex: Int): Sequence = TODO("Wasm stdlib: Text") - - /** - * Splits the [input] CharSequence to a list of strings around matches of this regular expression. - * - * @param limit Non-negative value specifying the maximum number of substrings the string can be split to. - * Zero by default means no limit is set. - */ - actual fun split(input: CharSequence, limit: Int): List = TODO("Wasm stdlib: Text") - - /** - * Splits the [input] CharSequence to a sequence of strings around matches of this regular expression. - * - * @param limit Non-negative value specifying the maximum number of substrings the string can be split to. - * Zero by default means no limit is set. - * @sample samples.text.Regexps.splitToSequence - */ - public actual fun splitToSequence(input: CharSequence, limit: Int): Sequence = TODO("Wasm stdlib: Text") - - actual companion object { - actual fun fromLiteral(literal: String): Regex = TODO("Wasm stdlib: Text") - actual fun escape(literal: String): String = TODO("Wasm stdlib: Text") - actual fun escapeReplacement(literal: String): String = TODO("Wasm stdlib: Text") - } -} - -actual class MatchGroup { - actual val value: String = TODO("Wasm stdlib: Text") -} - -actual enum class RegexOption { - IGNORE_CASE, - MULTILINE -} - - -// From char.kt - -/** - * Returns `true` if this character is a Unicode high-surrogate code unit (also known as leading-surrogate code unit). - */ -public actual fun Char.isHighSurrogate(): Boolean = this in Char.MIN_HIGH_SURROGATE..Char.MAX_HIGH_SURROGATE - -/** - * 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 - -/** - * Converts this character to lower case using Unicode mapping rules of the invariant locale. - */ -@Deprecated("Use lowercaseChar() instead.", ReplaceWith("lowercaseChar()")) -@DeprecatedSinceKotlin(warningSince = "1.5") -public actual fun Char.toLowerCase(): Char = lowercaseCharImpl() - -/** - * Converts this character to lower case using Unicode mapping rules of the invariant locale. - * - * This function performs one-to-one character mapping. - * To support one-to-many character mapping use the [lowercase] function. - * If this character has no mapping equivalent, the character itself is returned. - * - * @sample samples.text.Chars.lowercase - */ -@SinceKotlin("1.5") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun Char.lowercaseChar(): Char = lowercaseCharImpl() - -/** - * Converts this character to lower case using Unicode mapping rules of the invariant locale. - * - * This function supports one-to-many character mapping, thus the length of the returned string can be greater than one. - * For example, `'\u0130'.lowercase()` returns `"\u0069\u0307"`, - * where `'\u0130'` is the LATIN CAPITAL LETTER I WITH DOT ABOVE character (`İ`). - * If this character has no lower case mapping, the result of `toString()` of this char is returned. - * - * @sample samples.text.Chars.lowercase - */ -@SinceKotlin("1.5") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun Char.lowercase(): String = lowercaseImpl() - -/** - * Converts this character to upper case using Unicode mapping rules of the invariant locale. - */ -@Deprecated("Use uppercaseChar() instead.", ReplaceWith("uppercaseChar()")) -@DeprecatedSinceKotlin(warningSince = "1.5") -public actual fun Char.toUpperCase(): Char = uppercaseCharImpl() - -/** - * Converts this character to upper case using Unicode mapping rules of the invariant locale. - * - * This function performs one-to-one character mapping. - * To support one-to-many character mapping use the [uppercase] function. - * If this character has no mapping equivalent, the character itself is returned. - * - * @sample samples.text.Chars.uppercase - */ -@SinceKotlin("1.5") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun Char.uppercaseChar(): Char = uppercaseCharImpl() - -/** - * Converts this character to upper case using Unicode mapping rules of the invariant locale. - * - * This function supports one-to-many character mapping, thus the length of the returned string can be greater than one. - * For example, `'\uFB00'.uppercase()` returns `"\u0046\u0046"`, - * where `'\uFB00'` is the LATIN SMALL LIGATURE FF character (`ff`). - * If this character has no upper case mapping, the result of `toString()` of this char is returned. - * - * @sample samples.text.Chars.uppercase - */ -@SinceKotlin("1.5") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun Char.uppercase(): String = uppercaseImpl() - -/** - * Converts this character to title case using Unicode mapping rules of the invariant locale. - * - * This function performs one-to-one character mapping. - * To support one-to-many character mapping use the [titlecase] function. - * If this character has no mapping equivalent, the result of calling [uppercaseChar] is returned. - * - * @sample samples.text.Chars.titlecase - */ -@SinceKotlin("1.5") -public actual fun Char.titlecaseChar(): Char = titlecaseCharImpl() - - -/** - * Returns the Unicode general category of this character. - */ -@SinceKotlin("1.5") -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]. - */ -@SinceKotlin("1.5") -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 - */ -@SinceKotlin("1.5") -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 - */ -@SinceKotlin("1.5") -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 isDigit() || isLetter() -} - -/** - * 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 - */ -@SinceKotlin("1.5") -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 - */ -@SinceKotlin("1.5") -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 - */ -@SinceKotlin("1.5") -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 - */ -@SinceKotlin("1.5") -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 - */ -@SinceKotlin("1.5") -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() - -// From string.kt - - -/** - * Converts the characters in the specified array to a string. - */ -@SinceKotlin("1.2") -@Deprecated("Use CharArray.concatToString() instead", ReplaceWith("chars.concatToString()")) -@DeprecatedSinceKotlin(warningSince = "1.4", errorSince = "1.5") -public actual fun String(chars: CharArray): String { - var result = "" - for (char in chars) { - result += char - } - return result -} - -/** - * Converts the characters from a portion of the specified array to a string. - * - * @throws IndexOutOfBoundsException if either [offset] or [length] are less than zero - * or `offset + length` is out of [chars] array bounds. - */ -@SinceKotlin("1.2") -@Deprecated("Use CharArray.concatToString(startIndex, endIndex) instead", ReplaceWith("chars.concatToString(offset, offset + length)")) -@DeprecatedSinceKotlin(warningSince = "1.4", errorSince = "1.5") -public actual fun String(chars: CharArray, offset: Int, length: Int): String { - if (offset < 0 || length < 0 || chars.size - offset < length) - throw IndexOutOfBoundsException("size: ${chars.size}; offset: $offset; length: $length") - var result = "" - for (index in offset until offset + length) { - result += chars[index] - } - return result -} - -/** - * Concatenates characters in this [CharArray] into a String. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun CharArray.concatToString(): String { - var result = "" - for (char in this) { - result += char - } - return result -} - -/** - * Concatenates characters in this [CharArray] or its subrange into a String. - * - * @param startIndex the beginning (inclusive) of the subrange of characters, 0 by default. - * @param endIndex the end (exclusive) of the subrange of characters, size of this array by default. - * - * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. - * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun CharArray.concatToString(startIndex: Int = 0, endIndex: Int = this.size): String { - AbstractList.checkBoundsIndexes(startIndex, endIndex, this.size) - var result = "" - for (index in startIndex until endIndex) { - result += this[index] - } - return result -} - -/** - * Returns a [CharArray] containing characters of this string. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun String.toCharArray(): CharArray { - return CharArray(length) { get(it) } -} - -/** - * Returns a [CharArray] containing characters of this string or its substring. - * - * @param startIndex the beginning (inclusive) of the substring, 0 by default. - * @param endIndex the end (exclusive) of the substring, length of this string by default. - * - * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the length of this string. - * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.toCharArray(startIndex: Int = 0, endIndex: Int = this.length): CharArray { - AbstractList.checkBoundsIndexes(startIndex, endIndex, length) - return CharArray(endIndex - startIndex) { get(startIndex + it) } -} - -/** - * Decodes a string from the bytes in UTF-8 encoding in this array. - * - * Malformed byte sequences are replaced by the replacement char `\uFFFD`. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun ByteArray.decodeToString(): String { - return decodeUtf8(this, 0, size, false) -} - -/** - * Decodes a string from the bytes in UTF-8 encoding in this array or its subrange. - * - * @param startIndex the beginning (inclusive) of the subrange to decode, 0 by default. - * @param endIndex the end (exclusive) of the subrange to decode, size of this array by default. - * @param throwOnInvalidSequence specifies whether to throw an exception on malformed byte sequence or replace it by the replacement char `\uFFFD`. - * - * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. - * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. - * @throws CharacterCodingException if the byte array contains malformed UTF-8 byte sequence and [throwOnInvalidSequence] is true. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun ByteArray.decodeToString( - startIndex: Int = 0, - endIndex: Int = this.size, - throwOnInvalidSequence: Boolean = false -): String { - AbstractList.checkBoundsIndexes(startIndex, endIndex, this.size) - return decodeUtf8(this, startIndex, endIndex, throwOnInvalidSequence) -} - -/** - * Encodes this string to an array of bytes in UTF-8 encoding. - * - * Any malformed char sequence is replaced by the replacement byte sequence. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -public actual fun String.encodeToByteArray(): ByteArray { - return encodeUtf8(this, 0, length, false) -} - -/** - * Encodes this string or its substring to an array of bytes in UTF-8 encoding. - * - * @param startIndex the beginning (inclusive) of the substring to encode, 0 by default. - * @param endIndex the end (exclusive) of the substring to encode, length of this string by default. - * @param throwOnInvalidSequence specifies whether to throw an exception on malformed char sequence or replace. - * - * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the length of this string. - * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. - * @throws CharacterCodingException if this string contains malformed char sequence and [throwOnInvalidSequence] is true. - */ -@SinceKotlin("1.4") -@WasExperimental(ExperimentalStdlibApi::class) -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.encodeToByteArray( - startIndex: Int = 0, - endIndex: Int = this.length, - throwOnInvalidSequence: Boolean = false -): ByteArray { - AbstractList.checkBoundsIndexes(startIndex, endIndex, length) - return encodeUtf8(this, startIndex, endIndex, throwOnInvalidSequence) -} - -/** - * Returns a substring of this string that starts at the specified [startIndex] and continues to the end of the string. - */ -public actual fun String.substring(startIndex: Int): String = - subSequence(startIndex, this.length) as String - -/** - * Returns the substring of this string starting at the [startIndex] and ending right before the [endIndex]. - * - * @param startIndex the start index (inclusive). - * @param endIndex the end index (exclusive). - */ -public actual fun String.substring(startIndex: Int, endIndex: Int): String = - subSequence(startIndex, endIndex) as String - -/** - * Returns a copy of this string converted to upper case using the rules of the default locale. - */ -@Deprecated("Use uppercase() instead.", ReplaceWith("uppercase()")) -@DeprecatedSinceKotlin(warningSince = "1.5") -public actual fun String.toUpperCase(): String = uppercase() - -/** - * Returns a copy of this string converted to upper case using Unicode mapping rules of the invariant locale. - * - * This function supports one-to-many and many-to-one character mapping, - * thus the length of the returned string can be different from the length of the original string. - * - * @sample samples.text.Strings.uppercase - */ -@SinceKotlin("1.5") -public actual fun String.uppercase(): String = uppercaseImpl() - -/** - * Returns a copy of this string converted to lower case using the rules of the default locale. - */ -@Deprecated("Use lowercase() instead.", ReplaceWith("lowercase()")) -@DeprecatedSinceKotlin(warningSince = "1.5") -public actual fun String.toLowerCase(): String = lowercase() - -/** - * Returns a copy of this string converted to lower case using Unicode mapping rules of the invariant locale. - * - * This function supports one-to-many and many-to-one character mapping, - * thus the length of the returned string can be different from the length of the original string. - * - * @sample samples.text.Strings.lowercase - */ -@SinceKotlin("1.5") -public actual fun String.lowercase(): String = lowercaseImpl() - -/** - * Returns a copy of this string having its first letter titlecased using the rules of the default locale, - * or the original string if it's empty or already starts with a title case letter. - * - * The title case of a character is usually the same as its upper case with several exceptions. - * The particular list of characters with the special title case form depends on the underlying platform. - * - * @sample samples.text.Strings.capitalize - */ -@Deprecated("Use replaceFirstChar instead.", ReplaceWith("replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }")) -@DeprecatedSinceKotlin(warningSince = "1.5") -public actual fun String.capitalize(): String = replaceFirstChar(Char::uppercaseChar) - -/** - * Returns a copy of this string having its first letter lowercased using the rules of the default locale, - * or the original string if it's empty or already starts with a lower case letter. - * - * @sample samples.text.Strings.decapitalize - */ -@Deprecated("Use replaceFirstChar instead.", ReplaceWith("replaceFirstChar { it.lowercase() }")) -@DeprecatedSinceKotlin(warningSince = "1.5") -public actual fun String.decapitalize(): String = replaceFirstChar(Char::lowercaseChar) - -/** - * Returns a string containing this char sequence repeated [n] times. - * @throws [IllegalArgumentException] when n < 0. - * @sample samples.text.Strings.repeat - */ -public actual fun CharSequence.repeat(n: Int): String { - require(n >= 0) { "Count 'n' must be non-negative, but was $n." } - return when (n) { - 0 -> "" - 1 -> this.toString() - else -> { - var result = "" - if (!isEmpty()) { - var s = this.toString() - var count = n - while (true) { - if ((count and 1) == 1) { - result += s - } - count = count ushr 1 - if (count == 0) { - break - } - s += s - } - } - return result - } - } -} - -/** - * Returns a new string with all occurrences of [oldChar] replaced with [newChar]. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String { - return buildString(length) { - this@replace.forEach { c -> - append(if (c.equals(oldChar, ignoreCase)) newChar else c) - } - } -} - -/** - * Returns a new string obtained by replacing all occurrences of the [oldValue] substring in this string - * with the specified [newValue] string. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String { - run { - var occurrenceIndex: Int = indexOf(oldValue, 0, ignoreCase) - // FAST PATH: no match - if (occurrenceIndex < 0) return this - - val oldValueLength = oldValue.length - val searchStep = oldValueLength.coerceAtLeast(1) - val newLengthHint = length - oldValueLength + newValue.length - if (newLengthHint < 0) throw OutOfMemoryError() - val stringBuilder = StringBuilder(newLengthHint) - - var i = 0 - do { - stringBuilder.append(this, i, occurrenceIndex).append(newValue) - i = occurrenceIndex + oldValueLength - if (occurrenceIndex >= length) break - occurrenceIndex = indexOf(oldValue, occurrenceIndex + searchStep, ignoreCase) - } while (occurrenceIndex > 0) - return stringBuilder.append(this, i, length).toString() - } -} - -/** - * Returns a new string with the first occurrence of [oldChar] replaced with [newChar]. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.replaceFirst(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String { - val index = indexOf(oldChar, ignoreCase = ignoreCase) - return if (index < 0) this else this.replaceRange(index, index + 1, newChar.toString()) -} - -/** - * Returns a new string obtained by replacing the first occurrence of the [oldValue] substring in this string - * with the specified [newValue] string. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.replaceFirst(oldValue: String, newValue: String, ignoreCase: Boolean = false): String { - val index = indexOf(oldValue, ignoreCase = ignoreCase) - return if (index < 0) this else this.replaceRange(index, index + oldValue.length, newValue) -} - -/** - * Returns `true` if this string is equal to [other], optionally ignoring character case. - * - * Two strings are considered to be equal if they have the same length and the same character at the same index. - * If [ignoreCase] is true, the result of `Char.uppercaseChar().lowercaseChar()` on each character is compared. - * - * @param ignoreCase `true` to ignore character case when comparing strings. By default `false`. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean { - if (this == null) return other == null - if (other == null) return false - if (!ignoreCase) return this == other - - if (this.length != other.length) return false - - for (index in 0 until this.length) { - val thisChar = this[index] - val otherChar = other[index] - if (!thisChar.equals(otherChar, ignoreCase)) { - return false - } - } - - return true -} - -/** - * Compares two strings lexicographically, optionally ignoring case differences. - * - * If [ignoreCase] is true, the result of `Char.uppercaseChar().lowercaseChar()` on each character is compared. - */ -@SinceKotlin("1.2") -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.compareTo(other: String, ignoreCase: Boolean = false): Int { - if (ignoreCase) { - val n1 = this.length - val n2 = other.length - val min = minOf(n1, n2) - if (min == 0) return n1 - n2 - for (index in 0 until min) { - var thisChar = this[index] - var otherChar = other[index] - - if (thisChar != otherChar) { - thisChar = thisChar.uppercaseChar() - otherChar = otherChar.uppercaseChar() - - if (thisChar != otherChar) { - thisChar = thisChar.lowercaseChar() - otherChar = otherChar.lowercaseChar() - - if (thisChar != otherChar) { - return thisChar.compareTo(otherChar) - } - } - } - } - return n1 - n2 - } else { - return compareTo(other) - } -} - -/** - * Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], - * i.e. both char sequences contain the same number of the same characters in the same order. - * - * @sample samples.text.Strings.contentEquals - */ -@SinceKotlin("1.5") -public actual infix fun CharSequence?.contentEquals(other: CharSequence?): Boolean = contentEqualsImpl(other) - -/** - * Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], optionally ignoring case difference. - * - * @param ignoreCase `true` to ignore character case when comparing contents. - * - * @sample samples.text.Strings.contentEquals - */ -@SinceKotlin("1.5") -public actual fun CharSequence?.contentEquals(other: CharSequence?, ignoreCase: Boolean): Boolean { - return if (ignoreCase) - this.contentEqualsIgnoreCaseImpl(other) - else - this.contentEqualsImpl(other) -} - -/** - * Returns `true` if this string starts with the specified prefix. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.startsWith(prefix: String, ignoreCase: Boolean = false): Boolean = - regionMatches(0, prefix, 0, prefix.length, ignoreCase) - -/** - * Returns `true` if a substring of this string starting at the specified offset [startIndex] starts with the specified prefix. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.startsWith(prefix: String, startIndex: Int, ignoreCase: Boolean = false): Boolean = - regionMatches(startIndex, prefix, 0, prefix.length, ignoreCase) - -/** - * Returns `true` if this string ends with the specified suffix. - */ -@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") -public actual fun String.endsWith(suffix: String, ignoreCase: Boolean = false): Boolean = - regionMatches(length - suffix.length, suffix, 0, suffix.length, ignoreCase) - -// From stringsCode.kt - -/** - * Returns `true` if this string is empty or consists solely of whitespace characters. - * - * @sample samples.text.Strings.stringIsBlank - */ -public actual fun CharSequence.isBlank(): Boolean = length == 0 || indices.all { this[it].isWhitespace() } - -/** - * Returns `true` if the specified range in this char sequence is equal to the specified range in another char sequence. - * @param thisOffset the start offset in this char sequence of the substring to compare. - * @param other the string against a substring of which the comparison is performed. - * @param otherOffset the start offset in the other char sequence of the substring to compare. - * @param length the length of the substring to compare. - */ -actual fun CharSequence.regionMatches( - thisOffset: Int, - other: CharSequence, - otherOffset: Int, - length: Int, - ignoreCase: Boolean -): Boolean { - if ((otherOffset < 0) || (thisOffset < 0) || (thisOffset > this.length - length) || (otherOffset > other.length - length)) { - return false - } - - for (index in 0 until length) { - if (!this[thisOffset + index].equals(other[otherOffset + index], ignoreCase)) - return false - } - return true -} - -private val STRING_CASE_INSENSITIVE_ORDER = Comparator { a, b -> a.compareTo(b, ignoreCase = true) } - -/** - * A Comparator that orders strings ignoring character case. - * - * Note that this Comparator does not take locale into account, - * and will result in an unsatisfactory ordering for certain locales. - */ -@SinceKotlin("1.2") -public actual val String.Companion.CASE_INSENSITIVE_ORDER: Comparator - get() = STRING_CASE_INSENSITIVE_ORDER - -/** - * Returns `true` if the content of this string is equal to the word "true", ignoring case, and `false` otherwise. - */ -@Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") -@DeprecatedSinceKotlin(hiddenSince = "1.4") -@kotlin.internal.InlineOnly -actual fun String.toBoolean(): Boolean = this.toBoolean() - -/** - * Returns `true` if the contents of this string is equal to the word "true", ignoring case, and `false` otherwise. - * - * There are also strict versions of the function available on non-nullable String, [toBooleanStrict] and [toBooleanStrictOrNull]. - */ -actual fun String?.toBoolean(): Boolean = this != null && this.lowercase() == "true" - -/** - * Parses the string as a signed [Byte] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - */ -actual fun String.toByte(): Byte = toByteOrNull() ?: numberFormatError(this) - -/** - * Parses the string as a signed [Byte] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. - */ -public actual fun String.toByte(radix: Int): Byte = toByteOrNull(radix) ?: numberFormatError(this) - -/** - * Parses the string as a [Short] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - */ -public actual fun String.toShort(): Short = toShortOrNull() ?: numberFormatError(this) - -/** - * Parses the string as a [Short] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. - */ -public actual fun String.toShort(radix: Int): Short = toShortOrNull(radix) ?: numberFormatError(this) - -/** - * Parses the string as an [Int] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - */ -public actual fun String.toInt(): Int = toIntOrNull() ?: numberFormatError(this) - -/** - * Parses the string as an [Int] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. - */ -public actual fun String.toInt(radix: Int): Int = toIntOrNull(radix) ?: numberFormatError(this) - -/** - * Parses the string as a [Long] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - */ -public actual fun String.toLong(): Long = toLongOrNull() ?: numberFormatError(this) - -/** - * Parses the string as a [Long] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. - */ -public actual fun String.toLong(radix: Int): Long = toLongOrNull(radix) ?: numberFormatError(this) - -/** - * Parses the string as a [Double] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - */ -public actual fun String.toDouble(): Double = kotlin.text.parseDouble(this) - -/** - * Parses the string as a [Float] number and returns the result. - * @throws NumberFormatException if the string is not a valid representation of a number. - */ -public actual fun String.toFloat(): Float = toDouble() as Float - -/** - * Parses the string as a [Float] number and returns the result - * or `null` if the string is not a valid representation of a number. - */ -public actual fun String.toFloatOrNull(): Float? = toDoubleOrNull() as Float? - -/** - * Parses the string as a [Double] number and returns the result - * or `null` if the string is not a valid representation of a number. - */ -public actual fun String.toDoubleOrNull(): Double? { - try { - return toDouble() - } catch (e: NumberFormatException) { - return null - } -} - -/** - * Returns a string representation of this [Byte] value in the specified [radix]. - * - * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. - */ -@SinceKotlin("1.2") -public actual fun Byte.toString(radix: Int): String = this.toLong().toString(radix) - -/** - * Returns a string representation of this [Short] value in the specified [radix]. - * - * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. - */ -@SinceKotlin("1.2") -public actual fun Short.toString(radix: Int): String = this.toLong().toString(radix) - -/** - * Returns a string representation of this [Int] value in the specified [radix]. - * - * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. - */ -@SinceKotlin("1.2") -actual fun Int.toString(radix: Int): String = toLong().toString(radix) - -/** - * Returns a string representation of this [Long] value in the specified [radix]. - * - * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. - */ -@SinceKotlin("1.2") -actual fun Long.toString(radix: Int): String { - checkRadix(radix) - - fun Long.getChar() = toInt().let { if (it < 10) '0' + it else 'a' + (it - 10) } - - if (radix == 10) return toString() - if (this in 0 until radix) return getChar().toString() - - val isNegative = this < 0 - val buffer = CharArray(Long.SIZE_BITS + 1) - - var currentBufferIndex= buffer.lastIndex - var current: Long = this - while(current != 0L) { - buffer[currentBufferIndex] = abs(current % radix).getChar() - current /= radix - currentBufferIndex-- - } - - if (isNegative) { - buffer[currentBufferIndex] = '-' - currentBufferIndex-- - } - - return buffer.concatToString(currentBufferIndex + 1) -} - -@PublishedApi -internal actual fun checkRadix(radix: Int): Int { - if (radix !in Char.MIN_RADIX..Char.MAX_RADIX) { - throw IllegalArgumentException("radix $radix was not in valid range ${Char.MIN_RADIX..Char.MAX_RADIX}") - } - return radix -} - -internal actual fun digitOf(char: Char, radix: Int): Int = when { - char >= '0' && char <= '9' -> char - '0' - char >= 'A' && char <= 'Z' -> char - 'A' + 10 - char >= 'a' && char <= 'z' -> char - 'a' + 10 - char < '\u0080' -> -1 - char >= '\uFF21' && char <= '\uFF3A' -> char - '\uFF21' + 10 // full-width latin capital letter - char >= '\uFF41' && char <= '\uFF5A' -> char - '\uFF41' + 10 // full-width latin small letter - else -> char.digitToIntImpl() -}.let { if (it >= radix) -1 else it } diff --git a/libraries/stdlib/wasm/src/kotlin/text/Appendable.kt b/libraries/stdlib/wasm/src/kotlin/text/Appendable.kt deleted file mode 100644 index 3e251ef6edc..00000000000 --- a/libraries/stdlib/wasm/src/kotlin/text/Appendable.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - -/** - * An object to which char sequences and values can be appended. - */ -actual interface Appendable { - /** - * Appends the specified character [value] to this Appendable and returns this instance. - * - * @param value the character to append. - */ - actual fun append(value: Char): Appendable - - /** - * Appends the specified character sequence [value] to this Appendable and returns this instance. - * - * @param value the character sequence to append. If [value] is `null`, then the four characters `"null"` are appended to this Appendable. - */ - actual fun append(value: CharSequence?): Appendable - - /** - * Appends a subsequence of the specified character sequence [value] to this Appendable and returns this instance. - * - * @param value the character sequence from which a subsequence is appended. If [value] is `null`, - * then characters are appended as if [value] contained the four characters `"null"`. - * @param startIndex the beginning (inclusive) of the subsequence to append. - * @param endIndex the end (exclusive) of the subsequence to append. - * - * @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of the [value] character sequence indices or when `startIndex > endIndex`. - */ - actual fun append(value: CharSequence?, startIndex: Int, endIndex: Int): Appendable -} diff --git a/libraries/stdlib/wasm/src/kotlin/text/CharCategoryWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/CharCategoryWasm.kt deleted file mode 100644 index e512278b2c5..00000000000 --- a/libraries/stdlib/wasm/src/kotlin/text/CharCategoryWasm.kt +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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(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 = char.getCategoryValue() == this.value - - public companion object { - 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.") - } - - } -} diff --git a/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt index 06922997794..25b4ccf63f4 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt @@ -5,5 +5,34 @@ package kotlin.text -internal fun Char.Companion.toCodePoint(high: Char, low: Char): Int = - (((high - MIN_HIGH_SURROGATE) shl 10) or (low - MIN_LOW_SURROGATE)) + 0x10000 +/** + * 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 + */ +@SinceKotlin("1.5") +public actual fun Char.isISOControl(): Boolean { + return this <= '\u001F' || this in '\u007F'..'\u009F' +} + +/** + * Returns `true` if this character is a Unicode high-surrogate code unit (also known as leading-surrogate code unit). + */ +public actual fun Char.isHighSurrogate(): Boolean = this in Char.MIN_HIGH_SURROGATE..Char.MAX_HIGH_SURROGATE + +/** + * 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 + +internal actual fun digitOf(char: Char, radix: Int): Int = when { + char >= '0' && char <= '9' -> char - '0' + char >= 'A' && char <= 'Z' -> char - 'A' + 10 + char >= 'a' && char <= 'z' -> char - 'a' + 10 + char < '\u0080' -> -1 + char >= '\uFF21' && char <= '\uFF3A' -> char - '\uFF21' + 10 // full-width latin capital letter + char >= '\uFF41' && char <= '\uFF5A' -> char - '\uFF41' + 10 // full-width latin small letter + else -> char.digitToIntImpl() +}.let { if (it >= radix) -1 else it } \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/text/StringNumberConversionsWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/StringNumberConversionsWasm.kt new file mode 100644 index 00000000000..a99823b0a25 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/text/StringNumberConversionsWasm.kt @@ -0,0 +1,162 @@ +/* + * 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 + +import kotlin.math.abs + +/** + * Returns `true` if the content of this string is equal to the word "true", ignoring case, and `false` otherwise. + */ +@Deprecated("Use Kotlin compiler 1.4 to avoid deprecation warning.") +@DeprecatedSinceKotlin(hiddenSince = "1.4") +@kotlin.internal.InlineOnly +actual fun String.toBoolean(): Boolean = this.toBoolean() + +/** + * Returns `true` if the contents of this string is equal to the word "true", ignoring case, and `false` otherwise. + * + * There are also strict versions of the function available on non-nullable String, [toBooleanStrict] and [toBooleanStrictOrNull]. + */ +actual fun String?.toBoolean(): Boolean = this != null && this.lowercase() == "true" + +/** + * Parses the string as a signed [Byte] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + */ +actual fun String.toByte(): Byte = toByteOrNull() ?: numberFormatError(this) + +/** + * Parses the string as a signed [Byte] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. + */ +public actual fun String.toByte(radix: Int): Byte = toByteOrNull(radix) ?: numberFormatError(this) + +/** + * Parses the string as a [Short] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + */ +public actual fun String.toShort(): Short = toShortOrNull() ?: numberFormatError(this) + +/** + * Parses the string as a [Short] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. + */ +public actual fun String.toShort(radix: Int): Short = toShortOrNull(radix) ?: numberFormatError(this) + +/** + * Parses the string as an [Int] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + */ +public actual fun String.toInt(): Int = toIntOrNull() ?: numberFormatError(this) + +/** + * Parses the string as an [Int] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. + */ +public actual fun String.toInt(radix: Int): Int = toIntOrNull(radix) ?: numberFormatError(this) + +/** + * Parses the string as a [Long] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + */ +public actual fun String.toLong(): Long = toLongOrNull() ?: numberFormatError(this) + +/** + * Parses the string as a [Long] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + * @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion. + */ +public actual fun String.toLong(radix: Int): Long = toLongOrNull(radix) ?: numberFormatError(this) + +/** + * Parses the string as a [Double] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + */ +public actual fun String.toDouble(): Double = kotlin.text.parseDouble(this) + +/** + * Parses the string as a [Float] number and returns the result. + * @throws NumberFormatException if the string is not a valid representation of a number. + */ +public actual fun String.toFloat(): Float = toDouble() as Float + +/** + * Parses the string as a [Float] number and returns the result + * or `null` if the string is not a valid representation of a number. + */ +public actual fun String.toFloatOrNull(): Float? = toDoubleOrNull() as Float? + +/** + * Parses the string as a [Double] number and returns the result + * or `null` if the string is not a valid representation of a number. + */ +public actual fun String.toDoubleOrNull(): Double? { + try { + return toDouble() + } catch (e: NumberFormatException) { + return null + } +} + +/** + * Returns a string representation of this [Byte] value in the specified [radix]. + * + * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. + */ +@SinceKotlin("1.2") +public actual fun Byte.toString(radix: Int): String = this.toLong().toString(radix) + +/** + * Returns a string representation of this [Short] value in the specified [radix]. + * + * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. + */ +@SinceKotlin("1.2") +public actual fun Short.toString(radix: Int): String = this.toLong().toString(radix) + +/** + * Returns a string representation of this [Int] value in the specified [radix]. + * + * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. + */ +@SinceKotlin("1.2") +actual fun Int.toString(radix: Int): String = toLong().toString(radix) + +/** + * Returns a string representation of this [Long] value in the specified [radix]. + * + * @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion. + */ +@SinceKotlin("1.2") +actual fun Long.toString(radix: Int): String { + checkRadix(radix) + + fun Long.getChar() = toInt().let { if (it < 10) '0' + it else 'a' + (it - 10) } + + if (radix == 10) return toString() + if (this in 0 until radix) return getChar().toString() + + val isNegative = this < 0 + val buffer = CharArray(Long.SIZE_BITS + 1) + + var currentBufferIndex = buffer.lastIndex + var current: Long = this + while(current != 0L) { + buffer[currentBufferIndex] = abs(current % radix).getChar() + current /= radix + currentBufferIndex-- + } + + if (isNegative) { + buffer[currentBufferIndex] = '-' + currentBufferIndex-- + } + + return buffer.concatToString(currentBufferIndex + 1) +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt index 887460a9ca4..f24c16e048b 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt @@ -29,7 +29,7 @@ internal actual fun String.nativeLastIndexOf(ch: Char, fromIndex: Int): Int { * Returns the index within this string of the first occurrence of the specified substring, starting from the specified offset. */ internal actual fun String.nativeIndexOf(str: String, fromIndex: Int): Int { - for (index in fromIndex.coerceAtLeast(0)..this.length) { + for (index in fromIndex.coerceAtLeast(0)..(this.length - str.length)) { if (str.regionMatchesImpl(0, this, index, str.length, false)) { return index } @@ -41,10 +41,461 @@ internal actual fun String.nativeIndexOf(str: String, fromIndex: Int): Int { * Returns the index within this string of the last occurrence of the specified character, starting from the specified offset. */ internal actual fun String.nativeLastIndexOf(str: String, fromIndex: Int): Int { - for (index in fromIndex.coerceAtMost(this.lastIndex) downTo 0) { + for (index in fromIndex.coerceAtMost(this.length - str.length) downTo 0) { if (str.regionMatchesImpl(0, this, index, str.length, false)) { return index } } return -1 -} \ No newline at end of file +} + +/** + * Converts the characters in the specified array to a string. + */ +@SinceKotlin("1.2") +@Deprecated("Use CharArray.concatToString() instead", ReplaceWith("chars.concatToString()")) +@DeprecatedSinceKotlin(warningSince = "1.4", errorSince = "1.5") +public actual fun String(chars: CharArray): String { + var result = "" + for (char in chars) { + result += char + } + return result +} + +/** + * Converts the characters from a portion of the specified array to a string. + * + * @throws IndexOutOfBoundsException if either [offset] or [length] are less than zero + * or `offset + length` is out of [chars] array bounds. + */ +@SinceKotlin("1.2") +@Deprecated("Use CharArray.concatToString(startIndex, endIndex) instead", ReplaceWith("chars.concatToString(offset, offset + length)")) +@DeprecatedSinceKotlin(warningSince = "1.4", errorSince = "1.5") +public actual fun String(chars: CharArray, offset: Int, length: Int): String { + if (offset < 0 || length < 0 || chars.size - offset < length) + throw IndexOutOfBoundsException("size: ${chars.size}; offset: $offset; length: $length") + var result = "" + for (index in offset until offset + length) { + result += chars[index] + } + return result +} + +/** + * Concatenates characters in this [CharArray] into a String. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +public actual fun CharArray.concatToString(): String = + String.unsafeFromCharArray(this.copyOf()) + +/** + * Concatenates characters in this [CharArray] or its subrange into a String. + * + * @param startIndex the beginning (inclusive) of the subrange of characters, 0 by default. + * @param endIndex the end (exclusive) of the subrange of characters, size of this array by default. + * + * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun CharArray.concatToString(startIndex: Int = 0, endIndex: Int = this.size): String { + AbstractList.checkBoundsIndexes(startIndex, endIndex, this.size) + return String.unsafeFromCharArray(this.copyOfRange(startIndex, endIndex)) +} + +/** + * Returns a [CharArray] containing characters of this string. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +public actual fun String.toCharArray(): CharArray { + return CharArray(length) { get(it) } +} + +/** + * Returns a [CharArray] containing characters of this string or its substring. + * + * @param startIndex the beginning (inclusive) of the substring, 0 by default. + * @param endIndex the end (exclusive) of the substring, length of this string by default. + * + * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the length of this string. + * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.toCharArray(startIndex: Int = 0, endIndex: Int = this.length): CharArray { + AbstractList.checkBoundsIndexes(startIndex, endIndex, length) + return CharArray(endIndex - startIndex) { get(startIndex + it) } +} + +/** + * Decodes a string from the bytes in UTF-8 encoding in this array. + * + * Malformed byte sequences are replaced by the replacement char `\uFFFD`. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +public actual fun ByteArray.decodeToString(): String { + return decodeUtf8(this, 0, size, false) +} + +/** + * Decodes a string from the bytes in UTF-8 encoding in this array or its subrange. + * + * @param startIndex the beginning (inclusive) of the subrange to decode, 0 by default. + * @param endIndex the end (exclusive) of the subrange to decode, size of this array by default. + * @param throwOnInvalidSequence specifies whether to throw an exception on malformed byte sequence or replace it by the replacement char `\uFFFD`. + * + * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. + * @throws CharacterCodingException if the byte array contains malformed UTF-8 byte sequence and [throwOnInvalidSequence] is true. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun ByteArray.decodeToString( + startIndex: Int = 0, + endIndex: Int = this.size, + throwOnInvalidSequence: Boolean = false +): String { + AbstractList.checkBoundsIndexes(startIndex, endIndex, this.size) + return decodeUtf8(this, startIndex, endIndex, throwOnInvalidSequence) +} + +/** + * Encodes this string to an array of bytes in UTF-8 encoding. + * + * Any malformed char sequence is replaced by the replacement byte sequence. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +public actual fun String.encodeToByteArray(): ByteArray { + return encodeUtf8(this, 0, length, false) +} + +/** + * Encodes this string or its substring to an array of bytes in UTF-8 encoding. + * + * @param startIndex the beginning (inclusive) of the substring to encode, 0 by default. + * @param endIndex the end (exclusive) of the substring to encode, length of this string by default. + * @param throwOnInvalidSequence specifies whether to throw an exception on malformed char sequence or replace. + * + * @throws IndexOutOfBoundsException if [startIndex] is less than zero or [endIndex] is greater than the length of this string. + * @throws IllegalArgumentException if [startIndex] is greater than [endIndex]. + * @throws CharacterCodingException if this string contains malformed char sequence and [throwOnInvalidSequence] is true. + */ +@SinceKotlin("1.4") +@WasExperimental(ExperimentalStdlibApi::class) +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.encodeToByteArray( + startIndex: Int = 0, + endIndex: Int = this.length, + throwOnInvalidSequence: Boolean = false +): ByteArray { + AbstractList.checkBoundsIndexes(startIndex, endIndex, length) + return encodeUtf8(this, startIndex, endIndex, throwOnInvalidSequence) +} + +/** + * Returns a substring of this string that starts at the specified [startIndex] and continues to the end of the string. + */ +public actual fun String.substring(startIndex: Int): String = + subSequence(startIndex, this.length) as String + +/** + * Returns the substring of this string starting at the [startIndex] and ending right before the [endIndex]. + * + * @param startIndex the start index (inclusive). + * @param endIndex the end index (exclusive). + */ +public actual fun String.substring(startIndex: Int, endIndex: Int): String = + subSequence(startIndex, endIndex) as String + +/** + * Returns a copy of this string converted to upper case using the rules of the default locale. + */ +@Deprecated("Use uppercase() instead.", ReplaceWith("uppercase()")) +@DeprecatedSinceKotlin(warningSince = "1.5") +public actual fun String.toUpperCase(): String = uppercase() + +/** + * Returns a copy of this string converted to upper case using Unicode mapping rules of the invariant locale. + * + * This function supports one-to-many and many-to-one character mapping, + * thus the length of the returned string can be different from the length of the original string. + * + * @sample samples.text.Strings.uppercase + */ +@SinceKotlin("1.5") +public actual fun String.uppercase(): String = uppercaseImpl() + +/** + * Returns a copy of this string converted to lower case using the rules of the default locale. + */ +@Deprecated("Use lowercase() instead.", ReplaceWith("lowercase()")) +@DeprecatedSinceKotlin(warningSince = "1.5") +public actual fun String.toLowerCase(): String = lowercase() + +/** + * Returns a copy of this string converted to lower case using Unicode mapping rules of the invariant locale. + * + * This function supports one-to-many and many-to-one character mapping, + * thus the length of the returned string can be different from the length of the original string. + * + * @sample samples.text.Strings.lowercase + */ +@SinceKotlin("1.5") +public actual fun String.lowercase(): String = lowercaseImpl() + +/** + * Returns a copy of this string having its first letter titlecased using the rules of the default locale, + * or the original string if it's empty or already starts with a title case letter. + * + * The title case of a character is usually the same as its upper case with several exceptions. + * The particular list of characters with the special title case form depends on the underlying platform. + * + * @sample samples.text.Strings.capitalize + */ +@Deprecated("Use replaceFirstChar instead.", ReplaceWith("replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }")) +@DeprecatedSinceKotlin(warningSince = "1.5") +public actual fun String.capitalize(): String = replaceFirstChar(Char::uppercaseChar) + +/** + * Returns a copy of this string having its first letter lowercased using the rules of the default locale, + * or the original string if it's empty or already starts with a lower case letter. + * + * @sample samples.text.Strings.decapitalize + */ +@Deprecated("Use replaceFirstChar instead.", ReplaceWith("replaceFirstChar { it.lowercase() }")) +@DeprecatedSinceKotlin(warningSince = "1.5") +public actual fun String.decapitalize(): String = replaceFirstChar(Char::lowercaseChar) + +/** + * Returns a string containing this char sequence repeated [n] times. + * @throws [IllegalArgumentException] when n < 0. + * @sample samples.text.Strings.repeat + */ +public actual fun CharSequence.repeat(n: Int): String { + require(n >= 0) { "Count 'n' must be non-negative, but was $n." } + if (isEmpty()) return "" + return when (n) { + 0 -> "" + 1 -> this.toString() + else -> { + buildString(n * length) { + repeat(n) { + append(this@repeat) + } + } + } + } +} + +/** + * Returns a new string with all occurrences of [oldChar] replaced with [newChar]. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String { + return buildString(length) { + this@replace.forEach { c -> + append(if (c.equals(oldChar, ignoreCase)) newChar else c) + } + } +} + +/** + * Returns a new string obtained by replacing all occurrences of the [oldValue] substring in this string + * with the specified [newValue] string. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String { + run { + var occurrenceIndex: Int = indexOf(oldValue, 0, ignoreCase) + // FAST PATH: no match + if (occurrenceIndex < 0) return this + + val oldValueLength = oldValue.length + val searchStep = oldValueLength.coerceAtLeast(1) + val newLengthHint = length - oldValueLength + newValue.length + if (newLengthHint < 0) throw OutOfMemoryError() + val stringBuilder = StringBuilder(newLengthHint) + + var i = 0 + do { + stringBuilder.append(this, i, occurrenceIndex).append(newValue) + i = occurrenceIndex + oldValueLength + if (occurrenceIndex >= length) break + occurrenceIndex = indexOf(oldValue, occurrenceIndex + searchStep, ignoreCase) + } while (occurrenceIndex > 0) + return stringBuilder.append(this, i, length).toString() + } +} + +/** + * Returns a new string with the first occurrence of [oldChar] replaced with [newChar]. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.replaceFirst(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String { + val index = indexOf(oldChar, ignoreCase = ignoreCase) + return if (index < 0) this else this.replaceRange(index, index + 1, newChar.toString()) +} + +/** + * Returns a new string obtained by replacing the first occurrence of the [oldValue] substring in this string + * with the specified [newValue] string. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.replaceFirst(oldValue: String, newValue: String, ignoreCase: Boolean = false): String { + val index = indexOf(oldValue, ignoreCase = ignoreCase) + return if (index < 0) this else this.replaceRange(index, index + oldValue.length, newValue) +} + +/** + * Returns `true` if this string is equal to [other], optionally ignoring character case. + * + * Two strings are considered to be equal if they have the same length and the same character at the same index. + * If [ignoreCase] is true, the result of `Char.uppercaseChar().lowercaseChar()` on each character is compared. + * + * @param ignoreCase `true` to ignore character case when comparing strings. By default `false`. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean { + if (this == null) return other == null + if (other == null) return false + if (!ignoreCase) return this == other + + if (this.length != other.length) return false + + for (index in 0 until this.length) { + val thisChar = this[index] + val otherChar = other[index] + if (!thisChar.equals(otherChar, ignoreCase)) { + return false + } + } + + return true +} + +/** + * Compares two strings lexicographically, optionally ignoring case differences. + * + * If [ignoreCase] is true, the result of `Char.uppercaseChar().lowercaseChar()` on each character is compared. + */ +@SinceKotlin("1.2") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.compareTo(other: String, ignoreCase: Boolean = false): Int { + if (ignoreCase) { + val n1 = this.length + val n2 = other.length + val min = minOf(n1, n2) + if (min == 0) return n1 - n2 + for (index in 0 until min) { + var thisChar = this[index] + var otherChar = other[index] + + if (thisChar != otherChar) { + thisChar = thisChar.uppercaseChar() + otherChar = otherChar.uppercaseChar() + + if (thisChar != otherChar) { + thisChar = thisChar.lowercaseChar() + otherChar = otherChar.lowercaseChar() + + if (thisChar != otherChar) { + return thisChar.compareTo(otherChar) + } + } + } + } + return n1 - n2 + } else { + return compareTo(other) + } +} + +/** + * Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], + * i.e. both char sequences contain the same number of the same characters in the same order. + * + * @sample samples.text.Strings.contentEquals + */ +@SinceKotlin("1.5") +public actual infix fun CharSequence?.contentEquals(other: CharSequence?): Boolean = contentEqualsImpl(other) + +/** + * Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], optionally ignoring case difference. + * + * @param ignoreCase `true` to ignore character case when comparing contents. + * + * @sample samples.text.Strings.contentEquals + */ +@SinceKotlin("1.5") +public actual fun CharSequence?.contentEquals(other: CharSequence?, ignoreCase: Boolean): Boolean { + return if (ignoreCase) + this.contentEqualsIgnoreCaseImpl(other) + else + this.contentEqualsImpl(other) +} + +/** + * Returns `true` if this string starts with the specified prefix. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.startsWith(prefix: String, ignoreCase: Boolean = false): Boolean = + regionMatches(0, prefix, 0, prefix.length, ignoreCase) + +/** + * Returns `true` if a substring of this string starting at the specified offset [startIndex] starts with the specified prefix. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.startsWith(prefix: String, startIndex: Int, ignoreCase: Boolean = false): Boolean = + regionMatches(startIndex, prefix, 0, prefix.length, ignoreCase) + +/** + * Returns `true` if this string ends with the specified suffix. + */ +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun String.endsWith(suffix: String, ignoreCase: Boolean = false): Boolean = + regionMatches(length - suffix.length, suffix, 0, suffix.length, ignoreCase) + +// From stringsCode.kt + +/** + * Returns `true` if this string is empty or consists solely of whitespace characters. + * + * @sample samples.text.Strings.stringIsBlank + */ +public actual fun CharSequence.isBlank(): Boolean = length == 0 || indices.all { this[it].isWhitespace() } + +/** + * Returns `true` if the specified range in this char sequence is equal to the specified range in another char sequence. + * @param thisOffset the start offset in this char sequence of the substring to compare. + * @param other the string against a substring of which the comparison is performed. + * @param otherOffset the start offset in the other char sequence of the substring to compare. + * @param length the length of the substring to compare. + */ +actual fun CharSequence.regionMatches( + thisOffset: Int, + other: CharSequence, + otherOffset: Int, + length: Int, + ignoreCase: Boolean +): Boolean = regionMatchesImpl(thisOffset, other, otherOffset, length, ignoreCase) + +private val STRING_CASE_INSENSITIVE_ORDER = Comparator { a, b -> a.compareTo(b, ignoreCase = true) } + +/** + * A Comparator that orders strings ignoring character case. + * + * Note that this Comparator does not take locale into account, + * and will result in an unsatisfactory ordering for certain locales. + */ +@SinceKotlin("1.2") +public actual val String.Companion.CASE_INSENSITIVE_ORDER: Comparator + get() = STRING_CASE_INSENSITIVE_ORDER \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt b/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt new file mode 100644 index 00000000000..58e07d50727 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt @@ -0,0 +1,257 @@ +/* + * 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.native + +/** + * A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index. + * (this is the stripped copy of K/N implementation for Regex) + * + * @constructor creates an empty bit set with the specified [size] + * @param size the size of one element in the array used to store bits. + */ +internal class BitSet constructor(size: Int = ELEMENT_SIZE) { + + companion object { + // Default size of one element in the array used to store bits. + private const val ELEMENT_SIZE = 64 + private const val MAX_BIT_OFFSET = ELEMENT_SIZE - 1 + private const val ALL_TRUE = -1L // 0xFFFF_FFFF_FFFF_FFFF + private const val ALL_FALSE = 0L // 0x0000_0000_0000_0000 + } + + private var bits: LongArray = LongArray(bitToElementSize(size)) + + private val lastIndex: Int + get() = size - 1 + + /** True if this BitSet contains no bits set to true. */ + val isEmpty: Boolean + get() = bits.all { it == ALL_FALSE } + + /** Actual number of bits available in the set. All bits with indices >= size assumed to be 0 */ + var size: Int = size + private set + + // Transforms a bit index into an element index in the `bits` array. + private val Int.elementIndex: Int + get() = this / ELEMENT_SIZE + + // Transforms a bit index in the set into a bit in the element of the `bits` array. + private val Int.bitOffset: Int + get() = this % ELEMENT_SIZE + + // Transforms a bit index in the set into pair of a `bits` element index and a bit index in the element. + private val Int.asBitCoordinates: Pair + get() = Pair(elementIndex, bitOffset) + + // Transforms a bit offset to the mask with only bit set corresponding to the offset. + private val Int.asMask: Long + get() = 0x1L shl this + + // Transforms a bit offset to the mask with only bits before the index (inclusive) set. + private val Int.asMaskBefore: Long + get() = getMaskBetween(0, this) + + // Transforms a bit offset to the mask with only bits after the index (inclusive) set. + private val Int.asMaskAfter: Long + get() = getMaskBetween(this, MAX_BIT_OFFSET) + + // Builds a masks with 1 between fromOffset and toOffset (both inclusive). + private fun getMaskBetween(fromOffset: Int, toOffset: Int): Long { + var res = 0L + val maskToAdd = fromOffset.asMask + for (i in fromOffset..toOffset) { + res = (res shl 1) or maskToAdd + } + return res + } + + // Transforms a size in bits to a size in elements of the `bits` array. + private fun bitToElementSize(bitSize: Int): Int = (bitSize + ELEMENT_SIZE - 1) / ELEMENT_SIZE + + // Transforms a pair of an element index and a bit offset to a bit index. + private fun bitIndex(elementIndex: Int, bitOffset: Int) = + elementIndex * ELEMENT_SIZE + bitOffset + + // Sets all bits after the last available bit (size - 1) to 0. + private fun clearUnusedTail() { + val (lastElementIndex, lastBitOffset) = lastIndex.asBitCoordinates + bits[bits.lastIndex] = bits[bits.lastIndex] and lastBitOffset.asMaskBefore + for (i in lastElementIndex + 1 until bits.size) { + bits[i] = ALL_FALSE + } + } + + // Internal function. Sets bits specified by the element index and the given mask to value. + private fun setBitsWithMask(elementIndex: Int, mask: Long, value: Boolean) { + val element = bits[elementIndex] + if (value) { + bits[elementIndex] = element or mask + } else { + bits[elementIndex] = element and mask.inv() + } + } + + /** + * Checks if index is valid and extends the `bits` array if the index exceeds its size. + * @throws [IndexOutOfBoundsException] if [index] < 0. + */ + private fun ensureCapacity(index: Int) { + if (index < 0) { + throw IndexOutOfBoundsException() + } + if (index >= size) { + size = index + 1 + if (index.elementIndex >= bits.size) { + // Create a new array containing the index-th bit. + bits = bits.copyOf(bitToElementSize(index + 1)) + } + // Set all bits after the index to 0. TODO: We can remove it. + clearUnusedTail() + } + } + + /** Set the bit specified to the specified value. */ + fun set(index: Int, value: Boolean = true) { + ensureCapacity(index) + val (elementIndex, offset) = index.asBitCoordinates + setBitsWithMask(elementIndex, offset.asMask, value) + } + + /** Sets the bits with indices between [from] (inclusive) and [to] (exclusive) to the specified value. */ + fun set(from : Int, to: Int, value: Boolean = true) = set(from until to, value) + + /** Sets the bits from the range specified to the specified value. */ + fun set(range: IntRange, value: Boolean = true) { + if (range.start < 0 || range.endInclusive < 0) { + throw IndexOutOfBoundsException() + } + if (range.start > range.endInclusive) { // Empty range. + return + } + ensureCapacity(range.endInclusive) + val (fromIndex, fromOffset) = range.start.asBitCoordinates + val (toIndex, toOffset) = range.endInclusive.asBitCoordinates + if (toIndex == fromIndex) { + val mask = getMaskBetween(fromOffset, toOffset) + setBitsWithMask(fromIndex, mask, value) + } else { + // Set bits in the first element. + setBitsWithMask(fromIndex, fromOffset.asMaskAfter, value) + // Set all bits of all elements (excluding border ones) to 0 or 1 depending. + for (index in fromIndex + 1 until toIndex) { + bits[index] = if (value) ALL_TRUE else ALL_FALSE + } + // Set bits in the last element + setBitsWithMask(toIndex, toOffset.asMaskBefore, value) + } + } + + + /** + * Returns an index of a next set (if [lookFor] == true) or clear + * (if [lookFor] == false) bit after [startIndex] (inclusive). + * Returns -1 (for [lookFor] == true) or [size] (for lookFor == false) + * if there is no such bits between [startIndex] and [size] - 1. + * @throws IndexOutOfBoundException if [startIndex] < 0. + */ + private fun nextBit(startIndex: Int, lookFor: Boolean): Int { + if (startIndex < 0) { + throw IndexOutOfBoundsException() + } + if (startIndex >= size) { + return if (lookFor) -1 else startIndex + } + val (startElementIndex, startOffset) = startIndex.asBitCoordinates + // Look for the next set bit in the first element. + var element = bits[startElementIndex] + for (offset in startOffset..MAX_BIT_OFFSET) { + val bit = element and (0x1L shl offset) != 0L + if (bit == lookFor) { // Look for not 0 if we need a set bit and look for 0 otherwise. + return bitIndex(startElementIndex, offset) + } + } + // Look for in the remaining elements. + for (index in startElementIndex + 1..bits.lastIndex) { + element = bits[index] + for (offset in 0..MAX_BIT_OFFSET) { + val bit = element and (0x1L shl offset) != 0L + if (bit == lookFor) { // Look for not 0 if we need a set bit and look for 0 otherwise. + return bitIndex(index, offset) + } + } + } + return if (lookFor) -1 else size + } + + /** + * Returns an index of a next bit which value is `true` after [startIndex] (inclusive). + * Returns -1 if there is no such bits after [startIndex]. + * @throws IndexOutOfBoundException if [startIndex] < 0. + */ + fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) + + /** + * Returns an index of a next bit which value is `false` after [startIndex] (inclusive). + * Returns [size] if there is no such bits between [startIndex] and [size] - 1 assuming that the set has an infinite + * sequence of `false` bits after (size - 1)-th. + * @throws IndexOutOfBoundException if [startIndex] < 0. + */ + fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) + + /** Returns a value of a bit with the [index] specified. */ + operator fun get(index: Int): Boolean { + if (index < 0) { + throw IndexOutOfBoundsException() + } + if (index >= size) { + return false + } + val (elementIndex, offset) = index.asBitCoordinates + return bits[elementIndex] and offset.asMask != 0L + } + + private inline fun doOperation(another: BitSet, operation: Long.(Long) -> Long) { + ensureCapacity(another.lastIndex) + var index = 0 + while (index < another.bits.size) { + bits[index] = operation(bits[index], another.bits[index]) + index++ + } + while (index < bits.size) { + bits[index] = operation(bits[index], ALL_FALSE) + index++ + } + } + + /** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun and(another: BitSet) = doOperation(another, Long::and) + + /** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun or(another: BitSet) = doOperation(another, Long::or) + + /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun xor(another: BitSet) = doOperation(another, Long::xor) + + /** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun andNot(another: BitSet) { + ensureCapacity(another.lastIndex) + var index = 0 + while (index < another.bits.size) { + bits[index] = bits[index] and another.bits[index].inv() + index++ + } + while (index < bits.size) { + bits[index] = bits[index] and ALL_TRUE + index++ + } + } + + /** Returns true if the specified BitSet has any bits set to true that are also set to true in this BitSet. */ + fun intersects(another: BitSet): Boolean = + (0 until minOf(bits.size, another.bits.size)).any { bits[it] and another.bits[it] != 0L } +} diff --git a/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt b/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt new file mode 100644 index 00000000000..7681490490d --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt @@ -0,0 +1,318 @@ +/* + * 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.regex + +/* Contains canonical classes (see http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt). */ +private val canonicalClassesKeys = intArrayOf( + 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, + 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, + 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, + 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, + 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 1155, 1156, 1157, 1158, + 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, + 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, + 1463, 1464, 1465, 1467, 1468, 1469, 1471, 1473, 1474, 1476, 1477, 1479, 1552, 1553, 1554, 1555, 1556, 1557, 1611, + 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, + 1648, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1759, 1760, 1761, 1762, 1763, 1764, 1767, 1768, 1770, 1771, 1772, + 1773, 1809, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, + 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 2364, 2381, 2385, 2386, 2387, 2388, 2492, 2509, 2620, + 2637, 2748, 2765, 2876, 2893, 3021, 3149, 3157, 3158, 3260, 3277, 3405, 3530, 3640, 3641, 3642, 3656, 3657, 3658, + 3659, 3768, 3769, 3784, 3785, 3786, 3787, 3864, 3865, 3893, 3895, 3897, 3953, 3954, 3956, 3962, 3963, 3964, 3965, + 3968, 3970, 3971, 3972, 3974, 3975, 4038, 4151, 4153, 4959, 5908, 5940, 6098, 6109, 6313, 6457, 6458, 6459, 6679, + 6680, 7616, 7617, 7618, 7619, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8411, 8412, 8417, + 8421, 8422, 8423, 8424, 8425, 8426, 8427, 12330, 12331, 12332, 12333, 12334, 12335, 12441, 12442, 43014, 64286, 65056, + 65057, 65058, 65059, 68109, 68111, 68152, 68153, 68154, 68159, 119141, 119142, 119143, 119144, 119145, 119149, 119150, + 119151, 119152, 119153, 119154, 119163, 119164, 119165, 119166, 119167, 119168, 119169, 119170, 119173, 119174, + 119175, 119176, 119177, 119178, 119179, 119210, 119211, 119212, 119213, 119362, 119363, 119364, +) + +private val canonicalClassesValues = intArrayOf( + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 232, 220, + 220, 220, 220, 232, 216, 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, + 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, + 220, 220, 220, 230, 230, 230, 220, 220, 230, 230, 230, 220, 220, 220, 220, 230, 232, 220, 220, 230, 233, 234, 234, + 233, 234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 220, 230, + 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 220, 220, 220, 220, 220, 220, 230, 230, + 220, 230, 230, 222, 228, 230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 230, 220, 18, 230, 230, + 230, 230, 230, 230, 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 35, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 230, 220, 230, 230, 220, 36, 230, 220, 230, 230, + 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 7, + 9, 230, 220, 230, 230, 7, 9, 7, 9, 7, 9, 7, 9, 9, 9, 84, 91, 7, 9, 9, 9, 103, 103, 9, 107, 107, 107, 107, 118, 118, + 122, 122, 122, 122, 220, 220, 220, 220, 216, 129, 130, 132, 130, 130, 130, 130, 130, 230, 230, 9, 230, 230, 220, 7, 9, + 230, 9, 9, 9, 230, 228, 222, 230, 220, 230, 220, 230, 230, 220, 230, 230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, + 230, 230, 1, 1, 230, 220, 230, 1, 1, 218, 228, 232, 222, 224, 224, 8, 8, 9, 26, 230, 230, 230, 230, 220, 230, 230, 1, + 220, 9, 216, 216, 1, 1, 1, 226, 216, 216, 216, 216, 216, 220, 220, 220, 220, 220, 220, 220, 220, 230, 230, 230, 230, + 230, 220, 220, 230, 230, 230, 230, 230, 230, 230, +) + +/* Symbols that are one symbol decompositions (see http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt). */ +private val singleDecompositions = intArrayOf( + 59, 75, 96, 180, 183, 197, 697, 768, 769, 787, 901, 902, 904, 905, 906, 908, 910, 911, 912, 937, 940, 941, 942, 943, + 944, 953, 972, 973, 974, 8194, 8195, 12296, 12297, 13470, 13497, 13499, 13535, 13589, 14062, 14076, 14209, 14383, + 14434, 14460, 14535, 14563, 14620, 14650, 14894, 14956, 15076, 15112, 15129, 15177, 15261, 15384, 15438, 15667, 15766, + 16044, 16056, 16155, 16380, 16392, 16408, 16441, 16454, 16534, 16611, 16687, 16898, 16935, 17056, 17153, 17204, 17241, + 17365, 17369, 17419, 17515, 17707, 17757, 17761, 17771, 17879, 17913, 17973, 18110, 18119, 18837, 18918, 19054, 19062, + 19122, 19251, 19406, 19662, 19693, 19704, 19798, 19981, 20006, 20018, 20024, 20025, 20029, 20033, 20098, 20102, 20142, + 20160, 20172, 20196, 20320, 20352, 20358, 20363, 20398, 20411, 20415, 20482, 20523, 20602, 20633, 20687, 20698, 20711, + 20800, 20805, 20813, 20820, 20836, 20839, 20840, 20841, 20845, 20855, 20864, 20877, 20882, 20885, 20887, 20900, 20908, + 20917, 20919, 20937, 20940, 20956, 20958, 20981, 20995, 20999, 21015, 21033, 21050, 21051, 21062, 21106, 21111, 21129, + 21147, 21155, 21171, 21191, 21193, 21202, 21214, 21220, 21237, 21242, 21253, 21254, 21271, 21311, 21321, 21329, 21338, + 21363, 21365, 21373, 21375, 21443, 21450, 21471, 21477, 21483, 21489, 21510, 21519, 21533, 21560, 21570, 21576, 21608, + 21662, 21666, 21693, 21750, 21776, 21843, 21845, 21859, 21892, 21895, 21913, 21917, 21931, 21939, 21952, 21954, 21986, + 22022, 22097, 22120, 22132, 22265, 22294, 22295, 22411, 22478, 22516, 22541, 22577, 22578, 22592, 22618, 22622, 22696, + 22700, 22707, 22744, 22751, 22766, 22770, 22775, 22790, 22810, 22818, 22852, 22856, 22865, 22868, 22882, 22899, 23000, + 23020, 23067, 23079, 23138, 23142, 23221, 23304, 23336, 23358, 23429, 23491, 23512, 23527, 23534, 23539, 23551, 23558, + 23586, 23615, 23648, 23650, 23652, 23653, 23662, 23693, 23744, 23833, 23875, 23888, 23915, 23918, 23932, 23986, 23994, + 24033, 24034, 24061, 24104, 24125, 24169, 24180, 24230, 24240, 24243, 24246, 24265, 24266, 24274, 24275, 24281, 24300, + 24318, 24324, 24354, 24403, 24418, 24425, 24427, 24459, 24474, 24489, 24493, 24525, 24535, 24565, 24569, 24594, 24604, + 24705, 24724, 24775, 24792, 24801, 24840, 24900, 24904, 24908, 24910, 24928, 24936, 24954, 24974, 24976, 24996, 25007, + 25010, 25054, 25074, 25078, 25088, 25104, 25115, 25134, 25140, 25181, 25265, 25289, 25295, 25299, 25300, 25340, 25342, + 25405, 25424, 25448, 25467, 25475, 25504, 25513, 25540, 25541, 25572, 25628, 25634, 25682, 25705, 25719, 25726, 25754, + 25757, 25796, 25935, 25942, 25964, 25976, 26009, 26053, 26082, 26083, 26131, 26185, 26228, 26248, 26257, 26268, 26292, + 26310, 26356, 26360, 26368, 26391, 26395, 26401, 26446, 26451, 26454, 26462, 26491, 26501, 26519, 26611, 26618, 26647, + 26655, 26706, 26753, 26757, 26766, 26792, 26900, 26946, 27043, 27114, 27138, 27155, 27304, 27347, 27355, 27396, 27425, + 27476, 27506, 27511, 27513, 27551, 27566, 27578, 27579, 27726, 27751, 27784, 27839, 27852, 27853, 27877, 27926, 27931, + 27934, 27956, 27966, 27969, 28009, 28010, 28023, 28024, 28037, 28107, 28122, 28138, 28153, 28186, 28207, 28270, 28316, + 28346, 28359, 28363, 28369, 28379, 28431, 28450, 28451, 28526, 28614, 28651, 28670, 28699, 28702, 28729, 28746, 28784, + 28791, 28797, 28825, 28845, 28872, 28889, 28997, 29001, 29038, 29084, 29134, 29136, 29200, 29211, 29224, 29227, 29237, + 29264, 29282, 29312, 29333, 29359, 29376, 29436, 29482, 29557, 29562, 29575, 29579, 29605, 29618, 29662, 29702, 29705, + 29730, 29767, 29788, 29801, 29809, 29829, 29833, 29848, 29898, 29958, 29988, 30011, 30014, 30041, 30053, 30064, 30178, + 30224, 30237, 30239, 30274, 30313, 30410, 30427, 30439, 30452, 30465, 30494, 30495, 30528, 30538, 30603, 30631, 30798, + 30827, 30860, 30865, 30922, 30924, 30971, 31018, 31036, 31038, 31048, 31049, 31056, 31062, 31069, 31070, 31077, 31103, + 31117, 31118, 31119, 31150, 31178, 31211, 31260, 31296, 31306, 31311, 31361, 31409, 31435, 31470, 31520, 31680, 31686, + 31689, 31806, 31840, 31867, 31890, 31934, 31954, 31958, 31971, 31975, 31976, 32000, 32016, 32034, 32047, 32091, 32099, + 32160, 32190, 32199, 32244, 32258, 32265, 32311, 32321, 32325, 32574, 32626, 32633, 32634, 32645, 32661, 32666, 32701, + 32762, 32769, 32773, 32838, 32864, 32879, 32880, 32894, 32907, 32941, 32946, 33027, 33086, 33240, 33256, 33261, 33281, + 33284, 33391, 33401, 33419, 33425, 33437, 33457, 33459, 33469, 33509, 33510, 33565, 33571, 33590, 33618, 33619, 33635, + 33709, 33725, 33737, 33738, 33740, 33756, 33767, 33775, 33777, 33853, 33865, 33879, 34030, 34033, 34035, 34044, 34070, + 34148, 34253, 34298, 34310, 34322, 34349, 34367, 34384, 34396, 34407, 34409, 34440, 34473, 34530, 34574, 34600, 34667, + 34681, 34694, 34746, 34785, 34817, 34847, 34892, 34912, 34915, 35010, 35023, 35031, 35038, 35041, 35064, 35066, 35088, + 35137, 35172, 35206, 35211, 35222, 35488, 35498, 35519, 35531, 35538, 35542, 35565, 35576, 35582, 35585, 35641, 35672, + 35712, 35722, 35912, 35925, 36011, 36033, 36034, 36040, 36051, 36104, 36123, 36215, 36284, 36299, 36335, 36336, 36554, + 36564, 36646, 36650, 36664, 36667, 36706, 36766, 36784, 36790, 36899, 36920, 36978, 36988, 37007, 37012, 37070, 37105, + 37117, 37137, 37147, 37226, 37273, 37300, 37324, 37327, 37329, 37428, 37432, 37494, 37500, 37591, 37592, 37636, 37706, + 37881, 37909, 38283, 38317, 38327, 38446, 38475, 38477, 38517, 38520, 38524, 38534, 38563, 38584, 38595, 38626, 38627, + 38646, 38647, 38691, 38706, 38728, 38742, 38875, 38880, 38911, 38923, 38936, 38953, 38971, 39006, 39138, 39151, 39164, + 39208, 39209, 39335, 39362, 39409, 39422, 39530, 39698, 39791, 40000, 40023, 40189, 40295, 40372, 40442, 40478, 40575, + 40599, 40607, 40635, 40654, 40697, 40702, 40709, 40719, 40726, 40763, 40771, 40845, 40846, 40860, 131362, 132380, + 132389, 132427, 132666, 133124, 133342, 133676, 133987, 136420, 136872, 136938, 137672, 138008, 138507, 138724, + 138726, 139651, 139679, 140081, 141012, 141380, 141386, 142092, 142321, 143370, 144056, 144223, 144275, 144284, + 144323, 144341, 144493, 145059, 145575, 146061, 146170, 146620, 146718, 147153, 147294, 147342, 148067, 148395, + 149000, 149301, 149524, 150582, 150674, 151457, 151480, 151620, 151794, 151795, 151833, 151859, 152137, 152605, + 153126, 153242, 153285, 153980, 154279, 154539, 154752, 154832, 155526, 156122, 156200, 156231, 156377, 156478, + 156890, 156963, 157096, 157607, 157621, 158524, 158774, 158933, 159083, 159532, 159665, 159954, 160714, 161383, + 161966, 162150, 162984, 163539, 163631, 165330, 165357, 165678, 166906, 167287, 168261, 168415, 168474, 168970, + 169110, 169398, 170800, 172238, 172293, 172558, 172689, 172946, 173568 +) + +private val decompositionKeys = intArrayOf( + 192, 193, 194, 195, 196, 197, 199, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 217, 218, + 219, 220, 221, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 241, 242, 243, 244, 245, + 246, 249, 250, 251, 252, 253, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 308, 309, 310, 311, 313, 314, 315, 316, 317, 318, 323, 324, 325, 326, 327, 328, 332, + 333, 334, 335, 336, 337, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 416, 417, 431, 432, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 478, 479, 480, + 481, 482, 483, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 500, 501, 504, 505, 506, 507, 508, 509, 510, + 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, + 534, 535, 536, 537, 538, 539, 542, 543, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 832, + 833, 835, 836, 884, 894, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 938, 939, 940, 941, 942, 943, 944, 970, + 971, 972, 973, 974, 979, 980, 1024, 1025, 1027, 1031, 1036, 1037, 1038, 1049, 1081, 1104, 1105, 1107, 1111, 1116, + 1117, 1118, 1142, 1143, 1217, 1218, 1232, 1233, 1234, 1235, 1238, 1239, 1242, 1243, 1244, 1245, 1246, 1247, 1250, + 1251, 1252, 1253, 1254, 1255, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1272, 1273, + 1570, 1571, 1572, 1573, 1574, 1728, 1730, 1747, 2345, 2353, 2356, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, + 2507, 2508, 2524, 2525, 2527, 2611, 2614, 2649, 2650, 2651, 2654, 2888, 2891, 2892, 2908, 2909, 2964, 3018, 3019, + 3020, 3144, 3264, 3271, 3272, 3274, 3275, 3402, 3403, 3404, 3546, 3548, 3549, 3550, 3907, 3917, 3922, 3927, 3932, + 3945, 3955, 3957, 3958, 3960, 3969, 3987, 3997, 4002, 4007, 4012, 4025, 4134, 7680, 7681, 7682, 7683, 7684, 7685, + 7686, 7687, 7688, 7689, 7690, 7691, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7702, 7703, 7704, + 7705, 7706, 7707, 7708, 7709, 7710, 7711, 7712, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, + 7724, 7725, 7726, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, + 7743, 7744, 7745, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, 7760, 7761, + 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7772, 7773, 7774, 7775, 7776, 7777, 7778, 7779, 7780, + 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7788, 7789, 7790, 7791, 7792, 7793, 7794, 7795, 7796, 7797, 7798, 7799, + 7800, 7801, 7802, 7803, 7804, 7805, 7806, 7807, 7808, 7809, 7810, 7811, 7812, 7813, 7814, 7815, 7816, 7817, 7818, + 7819, 7820, 7821, 7822, 7823, 7824, 7825, 7826, 7827, 7828, 7829, 7830, 7831, 7832, 7833, 7835, 7840, 7841, 7842, + 7843, 7844, 7845, 7846, 7847, 7848, 7849, 7850, 7851, 7852, 7853, 7854, 7855, 7856, 7857, 7858, 7859, 7860, 7861, + 7862, 7863, 7864, 7865, 7866, 7867, 7868, 7869, 7870, 7871, 7872, 7873, 7874, 7875, 7876, 7877, 7878, 7879, 7880, + 7881, 7882, 7883, 7884, 7885, 7886, 7887, 7888, 7889, 7890, 7891, 7892, 7893, 7894, 7895, 7896, 7897, 7898, 7899, + 7900, 7901, 7902, 7903, 7904, 7905, 7906, 7907, 7908, 7909, 7910, 7911, 7912, 7913, 7914, 7915, 7916, 7917, 7918, + 7919, 7920, 7921, 7922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, + 7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7960, 7961, 7962, 7963, 7964, + 7965, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 7984, 7985, + 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 8000, 8001, 8002, 8003, 8004, + 8005, 8008, 8009, 8010, 8011, 8012, 8013, 8016, 8017, 8018, 8019, 8020, 8021, 8022, 8023, 8025, 8027, 8029, 8031, + 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 8048, 8049, 8050, + 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071, + 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, + 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8105, 8106, 8107, 8108, 8109, + 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8118, 8119, 8120, 8121, 8122, 8123, 8124, 8126, 8129, 8130, 8131, 8132, + 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8150, 8151, 8152, 8153, 8154, + 8155, 8157, 8158, 8159, 8160, 8161, 8162, 8163, 8164, 8165, 8166, 8167, 8168, 8169, 8170, 8171, 8172, 8173, 8174, + 8175, 8178, 8179, 8180, 8182, 8183, 8184, 8185, 8186, 8187, 8188, 8189, 8192, 8193, 8486, 8490, 8491, 8602, 8603, + 8622, 8653, 8654, 8655, 8708, 8713, 8716, 8740, 8742, 8769, 8772, 8775, 8777, 8800, 8802, 8813, 8814, 8815, 8816, + 8817, 8820, 8821, 8824, 8825, 8832, 8833, 8836, 8837, 8840, 8841, 8876, 8877, 8878, 8879, 8928, 8929, 8930, 8931, + 8938, 8939, 8940, 8941, 9001, 9002, 10972, 12364, 12366, 12368, 12370, 12372, 12374, 12376, 12378, 12380, 12382, + 12384, 12386, 12389, 12391, 12393, 12400, 12401, 12403, 12404, 12406, 12407, 12409, 12410, 12412, 12413, 12436, 12446, + 12460, 12462, 12464, 12466, 12468, 12470, 12472, 12474, 12476, 12478, 12480, 12482, 12485, 12487, 12489, 12496, 12497, + 12499, 12500, 12502, 12503, 12505, 12506, 12508, 12509, 12532, 12535, 12536, 12537, 12538, 12542, 63744, 63745, 63746, + 63747, 63748, 63749, 63750, 63751, 63752, 63753, 63754, 63755, 63756, 63757, 63758, 63759, 63760, 63761, 63762, 63763, + 63764, 63765, 63766, 63767, 63768, 63769, 63770, 63771, 63772, 63773, 63774, 63775, 63776, 63777, 63778, 63779, 63780, + 63781, 63782, 63783, 63784, 63785, 63786, 63787, 63788, 63789, 63790, 63791, 63792, 63793, 63794, 63795, 63796, 63797, + 63798, 63799, 63800, 63801, 63802, 63803, 63804, 63805, 63806, 63807, 63808, 63809, 63810, 63811, 63812, 63813, 63814, + 63815, 63816, 63817, 63818, 63819, 63820, 63821, 63822, 63823, 63824, 63825, 63826, 63827, 63828, 63829, 63830, 63831, + 63832, 63833, 63834, 63835, 63836, 63837, 63838, 63839, 63840, 63841, 63842, 63843, 63844, 63845, 63846, 63847, 63848, + 63849, 63850, 63851, 63852, 63853, 63854, 63855, 63856, 63857, 63858, 63859, 63860, 63861, 63862, 63863, 63864, 63865, + 63866, 63867, 63868, 63869, 63870, 63871, 63872, 63873, 63874, 63875, 63876, 63877, 63878, 63879, 63880, 63881, 63882, + 63883, 63884, 63885, 63886, 63887, 63888, 63889, 63890, 63891, 63892, 63893, 63894, 63895, 63896, 63897, 63898, 63899, + 63900, 63901, 63902, 63903, 63904, 63905, 63906, 63907, 63908, 63909, 63910, 63911, 63912, 63913, 63914, 63915, 63916, + 63917, 63918, 63919, 63920, 63921, 63922, 63923, 63924, 63925, 63926, 63927, 63928, 63929, 63930, 63931, 63932, 63933, + 63934, 63935, 63936, 63937, 63938, 63939, 63940, 63941, 63942, 63943, 63944, 63945, 63946, 63947, 63948, 63949, 63950, + 63951, 63952, 63953, 63954, 63955, 63956, 63957, 63958, 63959, 63960, 63961, 63962, 63963, 63964, 63965, 63966, 63967, + 63968, 63969, 63970, 63971, 63972, 63973, 63974, 63975, 63976, 63977, 63978, 63979, 63980, 63981, 63982, 63983, 63984, + 63985, 63986, 63987, 63988, 63989, 63990, 63991, 63992, 63993, 63994, 63995, 63996, 63997, 63998, 63999, 64000, 64001, + 64002, 64003, 64004, 64005, 64006, 64007, 64008, 64009, 64010, 64011, 64012, 64013, 64016, 64018, 64021, 64022, 64023, + 64024, 64025, 64026, 64027, 64028, 64029, 64030, 64032, 64034, 64037, 64038, 64042, 64043, 64044, 64045, 64048, 64049, + 64050, 64051, 64052, 64053, 64054, 64055, 64056, 64057, 64058, 64059, 64060, 64061, 64062, 64063, 64064, 64065, 64066, + 64067, 64068, 64069, 64070, 64071, 64072, 64073, 64074, 64075, 64076, 64077, 64078, 64079, 64080, 64081, 64082, 64083, + 64084, 64085, 64086, 64087, 64088, 64089, 64090, 64091, 64092, 64093, 64094, 64095, 64096, 64097, 64098, 64099, 64100, + 64101, 64102, 64103, 64104, 64105, 64106, 64112, 64113, 64114, 64115, 64116, 64117, 64118, 64119, 64120, 64121, 64122, + 64123, 64124, 64125, 64126, 64127, 64128, 64129, 64130, 64131, 64132, 64133, 64134, 64135, 64136, 64137, 64138, 64139, + 64140, 64141, 64142, 64143, 64144, 64145, 64146, 64147, 64148, 64149, 64150, 64151, 64152, 64153, 64154, 64155, 64156, + 64157, 64158, 64159, 64160, 64161, 64162, 64163, 64164, 64165, 64166, 64167, 64168, 64169, 64170, 64171, 64172, 64173, + 64174, 64175, 64176, 64177, 64178, 64179, 64180, 64181, 64182, 64183, 64184, 64185, 64186, 64187, 64188, 64189, 64190, + 64191, 64192, 64193, 64194, 64195, 64196, 64197, 64198, 64199, 64200, 64201, 64202, 64203, 64204, 64205, 64206, 64207, + 64208, 64209, 64210, 64211, 64212, 64213, 64214, 64215, 64216, 64217, 64285, 64287, 64298, 64299, 64300, 64301, 64302, + 64303, 64304, 64305, 64306, 64307, 64308, 64309, 64310, 64312, 64313, 64314, 64315, 64316, 64318, 64320, 64321, 64323, + 64324, 64326, 64327, 64328, 64329, 64330, 64331, 64332, 64333, 64334, 119134, 119135, 119136, 119137, 119138, 119139, + 119140, 119227, 119228, 119229, 119230, 119231, 119232, 194560, 194561, 194562, 194563, 194564, 194565, 194566, + 194567, 194568, 194569, 194570, 194571, 194572, 194573, 194574, 194575, 194576, 194577, 194578, 194579, 194580, + 194581, 194582, 194583, 194584, 194585, 194586, 194587, 194588, 194589, 194590, 194591, 194592, 194593, 194594, + 194595, 194596, 194597, 194598, 194599, 194600, 194601, 194602, 194603, 194604, 194605, 194606, 194607, 194608, + 194609, 194610, 194611, 194612, 194613, 194614, 194615, 194616, 194617, 194618, 194619, 194620, 194621, 194622, + 194623, 194624, 194625, 194626, 194627, 194628, 194629, 194630, 194631, 194632, 194633, 194634, 194635, 194636, + 194637, 194638, 194639, 194640, 194641, 194642, 194643, 194644, 194645, 194646, 194647, 194648, 194649, 194650, + 194651, 194652, 194653, 194654, 194655, 194656, 194657, 194658, 194659, 194660, 194661, 194662, 194663, 194664, + 194665, 194666, 194667, 194668, 194669, 194670, 194671, 194672, 194673, 194674, 194675, 194676, 194677, 194678, + 194679, 194680, 194681, 194682, 194683, 194684, 194685, 194686, 194687, 194688, 194689, 194690, 194691, 194692, + 194693, 194694, 194695, 194696, 194697, 194698, 194699, 194700, 194701, 194702, 194703, 194704, 194705, 194706, + 194707, 194708, 194709, 194710, 194711, 194712, 194713, 194714, 194715, 194716, 194717, 194718, 194719, 194720, + 194721, 194722, 194723, 194724, 194725, 194726, 194727, 194728, 194729, 194730, 194731, 194732, 194733, 194734, + 194735, 194736, 194737, 194738, 194739, 194740, 194741, 194742, 194743, 194744, 194745, 194746, 194747, 194748, + 194749, 194750, 194751, 194752, 194753, 194754, 194755, 194756, 194757, 194758, 194759, 194760, 194761, 194762, + 194763, 194764, 194765, 194766, 194767, 194768, 194769, 194770, 194771, 194772, 194773, 194774, 194775, 194776, + 194777, 194778, 194779, 194780, 194781, 194782, 194783, 194784, 194785, 194786, 194787, 194788, 194789, 194790, + 194791, 194792, 194793, 194794, 194795, 194796, 194797, 194798, 194799, 194800, 194801, 194802, 194803, 194804, + 194805, 194806, 194807, 194808, 194809, 194810, 194811, 194812, 194813, 194814, 194815, 194816, 194817, 194818, + 194819, 194820, 194821, 194822, 194823, 194824, 194825, 194826, 194827, 194828, 194829, 194830, 194831, 194832, + 194833, 194834, 194835, 194836, 194837, 194838, 194839, 194840, 194841, 194842, 194843, 194844, 194845, 194846, + 194847, 194848, 194849, 194850, 194851, 194852, 194853, 194854, 194855, 194856, 194857, 194858, 194859, 194860, + 194861, 194862, 194863, 194864, 194865, 194866, 194867, 194868, 194869, 194870, 194871, 194872, 194873, 194874, + 194875, 194876, 194877, 194878, 194879, 194880, 194881, 194882, 194883, 194884, 194885, 194886, 194887, 194888, + 194889, 194890, 194891, 194892, 194893, 194894, 194895, 194896, 194897, 194898, 194899, 194900, 194901, 194902, + 194903, 194904, 194905, 194906, 194907, 194908, 194909, 194910, 194911, 194912, 194913, 194914, 194915, 194916, + 194917, 194918, 194919, 194920, 194921, 194922, 194923, 194924, 194925, 194926, 194927, 194928, 194929, 194930, + 194931, 194932, 194933, 194934, 194935, 194936, 194937, 194938, 194939, 194940, 194941, 194942, 194943, 194944, + 194945, 194946, 194947, 194948, 194949, 194950, 194951, 194952, 194953, 194954, 194955, 194956, 194957, 194958, + 194959, 194960, 194961, 194962, 194963, 194964, 194965, 194966, 194967, 194968, 194969, 194970, 194971, 194972, + 194973, 194974, 194975, 194976, 194977, 194978, 194979, 194980, 194981, 194982, 194983, 194984, 194985, 194986, + 194987, 194988, 194989, 194990, 194991, 194992, 194993, 194994, 194995, 194996, 194997, 194998, 194999, 195000, + 195001, 195002, 195003, 195004, 195005, 195006, 195007, 195008, 195009, 195010, 195011, 195012, 195013, 195014, + 195015, 195016, 195017, 195018, 195019, 195020, 195021, 195022, 195023, 195024, 195025, 195026, 195027, 195028, + 195029, 195030, 195031, 195032, 195033, 195034, 195035, 195036, 195037, 195038, 195039, 195040, 195041, 195042, + 195043, 195044, 195045, 195046, 195047, 195048, 195049, 195050, 195051, 195052, 195053, 195054, 195055, 195056, + 195057, 195058, 195059, 195060, 195061, 195062, 195063, 195064, 195065, 195066, 195067, 195068, 195069, 195070, + 195071, 195072, 195073, 195074, 195075, 195076, 195077, 195078, 195079, 195080, 195081, 195082, 195083, 195084, + 195085, 195086, 195087, 195088, 195089, 195090, 195091, 195092, 195093, 195094, 195095, 195096, 195097, 195098, + 195099, 195100, 195101 +) + +private fun getCanonicalClass(ch: Int): Int { + val index: Int = binarySearchRange(canonicalClassesKeys, ch) + if (index == -1 || canonicalClassesKeys[index] != ch) { + return 0 + } + return canonicalClassesValues[index] +} + +private fun getDecomposition(codePoint: Int): IntArray? { + val index: Int = binarySearchRange(decompositionKeys, codePoint) + if (index == -1 || decompositionKeys[index] != codePoint) { + return null + } + return decompositionValues[index] +} + +/** Gets canonical class for given codepoint from decomposition mappings table. */ +internal fun getCanonicalClassInternal(ch: Int): Int { + return getCanonicalClass(ch) +} + +/** Check if the given character is in table of single decompositions. */ +internal fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean { + val index: Int = binarySearchRange(singleDecompositions, ch) + return index != -1 && singleDecompositions[index] == ch +} + +/** Returns a decomposition for a given codepoint. */ +internal fun getDecompositionInternal(ch: Int): IntArray? = getDecomposition(ch) + +/** + * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. + * Returns the length of the decomposition. + */ +internal fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int { + if (inputLength == 0) return 0 + + var outputLength = 0 + for (i in 0 until inputLength) { + val decomposition = getDecomposition(inputCodePoints[i]) + if (decomposition == null) { + outputCodePoints[outputLength++] = inputCodePoints[i] + } else { + decomposition.copyInto(outputCodePoints, outputLength) + outputLength += decomposition.size + } + } + return outputLength +} + +/** + * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. + * Returns the length of the decomposition. + */ +internal fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int { + val decomposition = getDecomposition(codePoint) + if (decomposition == null) { + outputCodePoints[fromIndex] = codePoint + return 1 + } else { + decomposition.copyInto(outputCodePoints, fromIndex) + return decomposition.size + } +} + +/** + * Returns the index of the largest element in [array] smaller or equal to the specified [needle], + * or -1 if [needle] is smaller than the smallest element in [array]. + */ +private 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) +} \ No newline at end of file diff --git a/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionValues.kt b/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionValues.kt new file mode 100644 index 00000000000..b33d9d4112e --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionValues.kt @@ -0,0 +1,2041 @@ +/* + * 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.regex + +internal val decompositionValues = arrayOf( + intArrayOf(65, 768), + intArrayOf(65, 769), + intArrayOf(65, 770), + intArrayOf(65, 771), + intArrayOf(65, 776), + intArrayOf(65, 778), + intArrayOf(67, 807), + intArrayOf(69, 768), + intArrayOf(69, 769), + intArrayOf(69, 770), + intArrayOf(69, 776), + intArrayOf(73, 768), + intArrayOf(73, 769), + intArrayOf(73, 770), + intArrayOf(73, 776), + intArrayOf(78, 771), + intArrayOf(79, 768), + intArrayOf(79, 769), + intArrayOf(79, 770), + intArrayOf(79, 771), + intArrayOf(79, 776), + intArrayOf(85, 768), + intArrayOf(85, 769), + intArrayOf(85, 770), + intArrayOf(85, 776), + intArrayOf(89, 769), + intArrayOf(97, 768), + intArrayOf(97, 769), + intArrayOf(97, 770), + intArrayOf(97, 771), + intArrayOf(97, 776), + intArrayOf(97, 778), + intArrayOf(99, 807), + intArrayOf(101, 768), + intArrayOf(101, 769), + intArrayOf(101, 770), + intArrayOf(101, 776), + intArrayOf(105, 768), + intArrayOf(105, 769), + intArrayOf(105, 770), + intArrayOf(105, 776), + intArrayOf(110, 771), + intArrayOf(111, 768), + intArrayOf(111, 769), + intArrayOf(111, 770), + intArrayOf(111, 771), + intArrayOf(111, 776), + intArrayOf(117, 768), + intArrayOf(117, 769), + intArrayOf(117, 770), + intArrayOf(117, 776), + intArrayOf(121, 769), + intArrayOf(121, 776), + intArrayOf(65, 772), + intArrayOf(97, 772), + intArrayOf(65, 774), + intArrayOf(97, 774), + intArrayOf(65, 808), + intArrayOf(97, 808), + intArrayOf(67, 769), + intArrayOf(99, 769), + intArrayOf(67, 770), + intArrayOf(99, 770), + intArrayOf(67, 775), + intArrayOf(99, 775), + intArrayOf(67, 780), + intArrayOf(99, 780), + intArrayOf(68, 780), + intArrayOf(100, 780), + intArrayOf(69, 772), + intArrayOf(101, 772), + intArrayOf(69, 774), + intArrayOf(101, 774), + intArrayOf(69, 775), + intArrayOf(101, 775), + intArrayOf(69, 808), + intArrayOf(101, 808), + intArrayOf(69, 780), + intArrayOf(101, 780), + intArrayOf(71, 770), + intArrayOf(103, 770), + intArrayOf(71, 774), + intArrayOf(103, 774), + intArrayOf(71, 775), + intArrayOf(103, 775), + intArrayOf(71, 807), + intArrayOf(103, 807), + intArrayOf(72, 770), + intArrayOf(104, 770), + intArrayOf(73, 771), + intArrayOf(105, 771), + intArrayOf(73, 772), + intArrayOf(105, 772), + intArrayOf(73, 774), + intArrayOf(105, 774), + intArrayOf(73, 808), + intArrayOf(105, 808), + intArrayOf(73, 775), + intArrayOf(74, 770), + intArrayOf(106, 770), + intArrayOf(75, 807), + intArrayOf(107, 807), + intArrayOf(76, 769), + intArrayOf(108, 769), + intArrayOf(76, 807), + intArrayOf(108, 807), + intArrayOf(76, 780), + intArrayOf(108, 780), + intArrayOf(78, 769), + intArrayOf(110, 769), + intArrayOf(78, 807), + intArrayOf(110, 807), + intArrayOf(78, 780), + intArrayOf(110, 780), + intArrayOf(79, 772), + intArrayOf(111, 772), + intArrayOf(79, 774), + intArrayOf(111, 774), + intArrayOf(79, 779), + intArrayOf(111, 779), + intArrayOf(82, 769), + intArrayOf(114, 769), + intArrayOf(82, 807), + intArrayOf(114, 807), + intArrayOf(82, 780), + intArrayOf(114, 780), + intArrayOf(83, 769), + intArrayOf(115, 769), + intArrayOf(83, 770), + intArrayOf(115, 770), + intArrayOf(83, 807), + intArrayOf(115, 807), + intArrayOf(83, 780), + intArrayOf(115, 780), + intArrayOf(84, 807), + intArrayOf(116, 807), + intArrayOf(84, 780), + intArrayOf(116, 780), + intArrayOf(85, 771), + intArrayOf(117, 771), + intArrayOf(85, 772), + intArrayOf(117, 772), + intArrayOf(85, 774), + intArrayOf(117, 774), + intArrayOf(85, 778), + intArrayOf(117, 778), + intArrayOf(85, 779), + intArrayOf(117, 779), + intArrayOf(85, 808), + intArrayOf(117, 808), + intArrayOf(87, 770), + intArrayOf(119, 770), + intArrayOf(89, 770), + intArrayOf(121, 770), + intArrayOf(89, 776), + intArrayOf(90, 769), + intArrayOf(122, 769), + intArrayOf(90, 775), + intArrayOf(122, 775), + intArrayOf(90, 780), + intArrayOf(122, 780), + intArrayOf(79, 795), + intArrayOf(111, 795), + intArrayOf(85, 795), + intArrayOf(117, 795), + intArrayOf(65, 780), + intArrayOf(97, 780), + intArrayOf(73, 780), + intArrayOf(105, 780), + intArrayOf(79, 780), + intArrayOf(111, 780), + intArrayOf(85, 780), + intArrayOf(117, 780), + intArrayOf(85, 776, 772), + intArrayOf(117, 776, 772), + intArrayOf(85, 776, 769), + intArrayOf(117, 776, 769), + intArrayOf(85, 776, 780), + intArrayOf(117, 776, 780), + intArrayOf(85, 776, 768), + intArrayOf(117, 776, 768), + intArrayOf(65, 776, 772), + intArrayOf(97, 776, 772), + intArrayOf(65, 775, 772), + intArrayOf(97, 775, 772), + intArrayOf(198, 772), + intArrayOf(230, 772), + intArrayOf(71, 780), + intArrayOf(103, 780), + intArrayOf(75, 780), + intArrayOf(107, 780), + intArrayOf(79, 808), + intArrayOf(111, 808), + intArrayOf(79, 808, 772), + intArrayOf(111, 808, 772), + intArrayOf(439, 780), + intArrayOf(658, 780), + intArrayOf(106, 780), + intArrayOf(71, 769), + intArrayOf(103, 769), + intArrayOf(78, 768), + intArrayOf(110, 768), + intArrayOf(65, 778, 769), + intArrayOf(97, 778, 769), + intArrayOf(198, 769), + intArrayOf(230, 769), + intArrayOf(216, 769), + intArrayOf(248, 769), + intArrayOf(65, 783), + intArrayOf(97, 783), + intArrayOf(65, 785), + intArrayOf(97, 785), + intArrayOf(69, 783), + intArrayOf(101, 783), + intArrayOf(69, 785), + intArrayOf(101, 785), + intArrayOf(73, 783), + intArrayOf(105, 783), + intArrayOf(73, 785), + intArrayOf(105, 785), + intArrayOf(79, 783), + intArrayOf(111, 783), + intArrayOf(79, 785), + intArrayOf(111, 785), + intArrayOf(82, 783), + intArrayOf(114, 783), + intArrayOf(82, 785), + intArrayOf(114, 785), + intArrayOf(85, 783), + intArrayOf(117, 783), + intArrayOf(85, 785), + intArrayOf(117, 785), + intArrayOf(83, 806), + intArrayOf(115, 806), + intArrayOf(84, 806), + intArrayOf(116, 806), + intArrayOf(72, 780), + intArrayOf(104, 780), + intArrayOf(65, 775), + intArrayOf(97, 775), + intArrayOf(69, 807), + intArrayOf(101, 807), + intArrayOf(79, 776, 772), + intArrayOf(111, 776, 772), + intArrayOf(79, 771, 772), + intArrayOf(111, 771, 772), + intArrayOf(79, 775), + intArrayOf(111, 775), + intArrayOf(79, 775, 772), + intArrayOf(111, 775, 772), + intArrayOf(89, 772), + intArrayOf(121, 772), + intArrayOf(768), + intArrayOf(769), + intArrayOf(787), + intArrayOf(776, 769), + intArrayOf(697), + intArrayOf(59), + intArrayOf(168, 769), + intArrayOf(913, 769), + intArrayOf(183), + intArrayOf(917, 769), + intArrayOf(919, 769), + intArrayOf(921, 769), + intArrayOf(927, 769), + intArrayOf(933, 769), + intArrayOf(937, 769), + intArrayOf(953, 776, 769), + intArrayOf(921, 776), + intArrayOf(933, 776), + intArrayOf(945, 769), + intArrayOf(949, 769), + intArrayOf(951, 769), + intArrayOf(953, 769), + intArrayOf(965, 776, 769), + intArrayOf(953, 776), + intArrayOf(965, 776), + intArrayOf(959, 769), + intArrayOf(965, 769), + intArrayOf(969, 769), + intArrayOf(978, 769), + intArrayOf(978, 776), + intArrayOf(1045, 768), + intArrayOf(1045, 776), + intArrayOf(1043, 769), + intArrayOf(1030, 776), + intArrayOf(1050, 769), + intArrayOf(1048, 768), + intArrayOf(1059, 774), + intArrayOf(1048, 774), + intArrayOf(1080, 774), + intArrayOf(1077, 768), + intArrayOf(1077, 776), + intArrayOf(1075, 769), + intArrayOf(1110, 776), + intArrayOf(1082, 769), + intArrayOf(1080, 768), + intArrayOf(1091, 774), + intArrayOf(1140, 783), + intArrayOf(1141, 783), + intArrayOf(1046, 774), + intArrayOf(1078, 774), + intArrayOf(1040, 774), + intArrayOf(1072, 774), + intArrayOf(1040, 776), + intArrayOf(1072, 776), + intArrayOf(1045, 774), + intArrayOf(1077, 774), + intArrayOf(1240, 776), + intArrayOf(1241, 776), + intArrayOf(1046, 776), + intArrayOf(1078, 776), + intArrayOf(1047, 776), + intArrayOf(1079, 776), + intArrayOf(1048, 772), + intArrayOf(1080, 772), + intArrayOf(1048, 776), + intArrayOf(1080, 776), + intArrayOf(1054, 776), + intArrayOf(1086, 776), + intArrayOf(1256, 776), + intArrayOf(1257, 776), + intArrayOf(1069, 776), + intArrayOf(1101, 776), + intArrayOf(1059, 772), + intArrayOf(1091, 772), + intArrayOf(1059, 776), + intArrayOf(1091, 776), + intArrayOf(1059, 779), + intArrayOf(1091, 779), + intArrayOf(1063, 776), + intArrayOf(1095, 776), + intArrayOf(1067, 776), + intArrayOf(1099, 776), + intArrayOf(1575, 1619), + intArrayOf(1575, 1620), + intArrayOf(1608, 1620), + intArrayOf(1575, 1621), + intArrayOf(1610, 1620), + intArrayOf(1749, 1620), + intArrayOf(1729, 1620), + intArrayOf(1746, 1620), + intArrayOf(2344, 2364), + intArrayOf(2352, 2364), + intArrayOf(2355, 2364), + intArrayOf(2325, 2364), + intArrayOf(2326, 2364), + intArrayOf(2327, 2364), + intArrayOf(2332, 2364), + intArrayOf(2337, 2364), + intArrayOf(2338, 2364), + intArrayOf(2347, 2364), + intArrayOf(2351, 2364), + intArrayOf(2503, 2494), + intArrayOf(2503, 2519), + intArrayOf(2465, 2492), + intArrayOf(2466, 2492), + intArrayOf(2479, 2492), + intArrayOf(2610, 2620), + intArrayOf(2616, 2620), + intArrayOf(2582, 2620), + intArrayOf(2583, 2620), + intArrayOf(2588, 2620), + intArrayOf(2603, 2620), + intArrayOf(2887, 2902), + intArrayOf(2887, 2878), + intArrayOf(2887, 2903), + intArrayOf(2849, 2876), + intArrayOf(2850, 2876), + intArrayOf(2962, 3031), + intArrayOf(3014, 3006), + intArrayOf(3015, 3006), + intArrayOf(3014, 3031), + intArrayOf(3142, 3158), + intArrayOf(3263, 3285), + intArrayOf(3270, 3285), + intArrayOf(3270, 3286), + intArrayOf(3270, 3266), + intArrayOf(3270, 3266, 3285), + intArrayOf(3398, 3390), + intArrayOf(3399, 3390), + intArrayOf(3398, 3415), + intArrayOf(3545, 3530), + intArrayOf(3545, 3535), + intArrayOf(3545, 3535, 3530), + intArrayOf(3545, 3551), + intArrayOf(3906, 4023), + intArrayOf(3916, 4023), + intArrayOf(3921, 4023), + intArrayOf(3926, 4023), + intArrayOf(3931, 4023), + intArrayOf(3904, 4021), + intArrayOf(3953, 3954), + intArrayOf(3953, 3956), + intArrayOf(4018, 3968), + intArrayOf(4019, 3968), + intArrayOf(3953, 3968), + intArrayOf(3986, 4023), + intArrayOf(3996, 4023), + intArrayOf(4001, 4023), + intArrayOf(4006, 4023), + intArrayOf(4011, 4023), + intArrayOf(3984, 4021), + intArrayOf(4133, 4142), + intArrayOf(65, 805), + intArrayOf(97, 805), + intArrayOf(66, 775), + intArrayOf(98, 775), + intArrayOf(66, 803), + intArrayOf(98, 803), + intArrayOf(66, 817), + intArrayOf(98, 817), + intArrayOf(67, 807, 769), + intArrayOf(99, 807, 769), + intArrayOf(68, 775), + intArrayOf(100, 775), + intArrayOf(68, 803), + intArrayOf(100, 803), + intArrayOf(68, 817), + intArrayOf(100, 817), + intArrayOf(68, 807), + intArrayOf(100, 807), + intArrayOf(68, 813), + intArrayOf(100, 813), + intArrayOf(69, 772, 768), + intArrayOf(101, 772, 768), + intArrayOf(69, 772, 769), + intArrayOf(101, 772, 769), + intArrayOf(69, 813), + intArrayOf(101, 813), + intArrayOf(69, 816), + intArrayOf(101, 816), + intArrayOf(69, 807, 774), + intArrayOf(101, 807, 774), + intArrayOf(70, 775), + intArrayOf(102, 775), + intArrayOf(71, 772), + intArrayOf(103, 772), + intArrayOf(72, 775), + intArrayOf(104, 775), + intArrayOf(72, 803), + intArrayOf(104, 803), + intArrayOf(72, 776), + intArrayOf(104, 776), + intArrayOf(72, 807), + intArrayOf(104, 807), + intArrayOf(72, 814), + intArrayOf(104, 814), + intArrayOf(73, 816), + intArrayOf(105, 816), + intArrayOf(73, 776, 769), + intArrayOf(105, 776, 769), + intArrayOf(75, 769), + intArrayOf(107, 769), + intArrayOf(75, 803), + intArrayOf(107, 803), + intArrayOf(75, 817), + intArrayOf(107, 817), + intArrayOf(76, 803), + intArrayOf(108, 803), + intArrayOf(76, 803, 772), + intArrayOf(108, 803, 772), + intArrayOf(76, 817), + intArrayOf(108, 817), + intArrayOf(76, 813), + intArrayOf(108, 813), + intArrayOf(77, 769), + intArrayOf(109, 769), + intArrayOf(77, 775), + intArrayOf(109, 775), + intArrayOf(77, 803), + intArrayOf(109, 803), + intArrayOf(78, 775), + intArrayOf(110, 775), + intArrayOf(78, 803), + intArrayOf(110, 803), + intArrayOf(78, 817), + intArrayOf(110, 817), + intArrayOf(78, 813), + intArrayOf(110, 813), + intArrayOf(79, 771, 769), + intArrayOf(111, 771, 769), + intArrayOf(79, 771, 776), + intArrayOf(111, 771, 776), + intArrayOf(79, 772, 768), + intArrayOf(111, 772, 768), + intArrayOf(79, 772, 769), + intArrayOf(111, 772, 769), + intArrayOf(80, 769), + intArrayOf(112, 769), + intArrayOf(80, 775), + intArrayOf(112, 775), + intArrayOf(82, 775), + intArrayOf(114, 775), + intArrayOf(82, 803), + intArrayOf(114, 803), + intArrayOf(82, 803, 772), + intArrayOf(114, 803, 772), + intArrayOf(82, 817), + intArrayOf(114, 817), + intArrayOf(83, 775), + intArrayOf(115, 775), + intArrayOf(83, 803), + intArrayOf(115, 803), + intArrayOf(83, 769, 775), + intArrayOf(115, 769, 775), + intArrayOf(83, 780, 775), + intArrayOf(115, 780, 775), + intArrayOf(83, 803, 775), + intArrayOf(115, 803, 775), + intArrayOf(84, 775), + intArrayOf(116, 775), + intArrayOf(84, 803), + intArrayOf(116, 803), + intArrayOf(84, 817), + intArrayOf(116, 817), + intArrayOf(84, 813), + intArrayOf(116, 813), + intArrayOf(85, 804), + intArrayOf(117, 804), + intArrayOf(85, 816), + intArrayOf(117, 816), + intArrayOf(85, 813), + intArrayOf(117, 813), + intArrayOf(85, 771, 769), + intArrayOf(117, 771, 769), + intArrayOf(85, 772, 776), + intArrayOf(117, 772, 776), + intArrayOf(86, 771), + intArrayOf(118, 771), + intArrayOf(86, 803), + intArrayOf(118, 803), + intArrayOf(87, 768), + intArrayOf(119, 768), + intArrayOf(87, 769), + intArrayOf(119, 769), + intArrayOf(87, 776), + intArrayOf(119, 776), + intArrayOf(87, 775), + intArrayOf(119, 775), + intArrayOf(87, 803), + intArrayOf(119, 803), + intArrayOf(88, 775), + intArrayOf(120, 775), + intArrayOf(88, 776), + intArrayOf(120, 776), + intArrayOf(89, 775), + intArrayOf(121, 775), + intArrayOf(90, 770), + intArrayOf(122, 770), + intArrayOf(90, 803), + intArrayOf(122, 803), + intArrayOf(90, 817), + intArrayOf(122, 817), + intArrayOf(104, 817), + intArrayOf(116, 776), + intArrayOf(119, 778), + intArrayOf(121, 778), + intArrayOf(383, 775), + intArrayOf(65, 803), + intArrayOf(97, 803), + intArrayOf(65, 777), + intArrayOf(97, 777), + intArrayOf(65, 770, 769), + intArrayOf(97, 770, 769), + intArrayOf(65, 770, 768), + intArrayOf(97, 770, 768), + intArrayOf(65, 770, 777), + intArrayOf(97, 770, 777), + intArrayOf(65, 770, 771), + intArrayOf(97, 770, 771), + intArrayOf(65, 803, 770), + intArrayOf(97, 803, 770), + intArrayOf(65, 774, 769), + intArrayOf(97, 774, 769), + intArrayOf(65, 774, 768), + intArrayOf(97, 774, 768), + intArrayOf(65, 774, 777), + intArrayOf(97, 774, 777), + intArrayOf(65, 774, 771), + intArrayOf(97, 774, 771), + intArrayOf(65, 803, 774), + intArrayOf(97, 803, 774), + intArrayOf(69, 803), + intArrayOf(101, 803), + intArrayOf(69, 777), + intArrayOf(101, 777), + intArrayOf(69, 771), + intArrayOf(101, 771), + intArrayOf(69, 770, 769), + intArrayOf(101, 770, 769), + intArrayOf(69, 770, 768), + intArrayOf(101, 770, 768), + intArrayOf(69, 770, 777), + intArrayOf(101, 770, 777), + intArrayOf(69, 770, 771), + intArrayOf(101, 770, 771), + intArrayOf(69, 803, 770), + intArrayOf(101, 803, 770), + intArrayOf(73, 777), + intArrayOf(105, 777), + intArrayOf(73, 803), + intArrayOf(105, 803), + intArrayOf(79, 803), + intArrayOf(111, 803), + intArrayOf(79, 777), + intArrayOf(111, 777), + intArrayOf(79, 770, 769), + intArrayOf(111, 770, 769), + intArrayOf(79, 770, 768), + intArrayOf(111, 770, 768), + intArrayOf(79, 770, 777), + intArrayOf(111, 770, 777), + intArrayOf(79, 770, 771), + intArrayOf(111, 770, 771), + intArrayOf(79, 803, 770), + intArrayOf(111, 803, 770), + intArrayOf(79, 795, 769), + intArrayOf(111, 795, 769), + intArrayOf(79, 795, 768), + intArrayOf(111, 795, 768), + intArrayOf(79, 795, 777), + intArrayOf(111, 795, 777), + intArrayOf(79, 795, 771), + intArrayOf(111, 795, 771), + intArrayOf(79, 795, 803), + intArrayOf(111, 795, 803), + intArrayOf(85, 803), + intArrayOf(117, 803), + intArrayOf(85, 777), + intArrayOf(117, 777), + intArrayOf(85, 795, 769), + intArrayOf(117, 795, 769), + intArrayOf(85, 795, 768), + intArrayOf(117, 795, 768), + intArrayOf(85, 795, 777), + intArrayOf(117, 795, 777), + intArrayOf(85, 795, 771), + intArrayOf(117, 795, 771), + intArrayOf(85, 795, 803), + intArrayOf(117, 795, 803), + intArrayOf(89, 768), + intArrayOf(121, 768), + intArrayOf(89, 803), + intArrayOf(121, 803), + intArrayOf(89, 777), + intArrayOf(121, 777), + intArrayOf(89, 771), + intArrayOf(121, 771), + intArrayOf(945, 787), + intArrayOf(945, 788), + intArrayOf(945, 787, 768), + intArrayOf(945, 788, 768), + intArrayOf(945, 787, 769), + intArrayOf(945, 788, 769), + intArrayOf(945, 787, 834), + intArrayOf(945, 788, 834), + intArrayOf(913, 787), + intArrayOf(913, 788), + intArrayOf(913, 787, 768), + intArrayOf(913, 788, 768), + intArrayOf(913, 787, 769), + intArrayOf(913, 788, 769), + intArrayOf(913, 787, 834), + intArrayOf(913, 788, 834), + intArrayOf(949, 787), + intArrayOf(949, 788), + intArrayOf(949, 787, 768), + intArrayOf(949, 788, 768), + intArrayOf(949, 787, 769), + intArrayOf(949, 788, 769), + intArrayOf(917, 787), + intArrayOf(917, 788), + intArrayOf(917, 787, 768), + intArrayOf(917, 788, 768), + intArrayOf(917, 787, 769), + intArrayOf(917, 788, 769), + intArrayOf(951, 787), + intArrayOf(951, 788), + intArrayOf(951, 787, 768), + intArrayOf(951, 788, 768), + intArrayOf(951, 787, 769), + intArrayOf(951, 788, 769), + intArrayOf(951, 787, 834), + intArrayOf(951, 788, 834), + intArrayOf(919, 787), + intArrayOf(919, 788), + intArrayOf(919, 787, 768), + intArrayOf(919, 788, 768), + intArrayOf(919, 787, 769), + intArrayOf(919, 788, 769), + intArrayOf(919, 787, 834), + intArrayOf(919, 788, 834), + intArrayOf(953, 787), + intArrayOf(953, 788), + intArrayOf(953, 787, 768), + intArrayOf(953, 788, 768), + intArrayOf(953, 787, 769), + intArrayOf(953, 788, 769), + intArrayOf(953, 787, 834), + intArrayOf(953, 788, 834), + intArrayOf(921, 787), + intArrayOf(921, 788), + intArrayOf(921, 787, 768), + intArrayOf(921, 788, 768), + intArrayOf(921, 787, 769), + intArrayOf(921, 788, 769), + intArrayOf(921, 787, 834), + intArrayOf(921, 788, 834), + intArrayOf(959, 787), + intArrayOf(959, 788), + intArrayOf(959, 787, 768), + intArrayOf(959, 788, 768), + intArrayOf(959, 787, 769), + intArrayOf(959, 788, 769), + intArrayOf(927, 787), + intArrayOf(927, 788), + intArrayOf(927, 787, 768), + intArrayOf(927, 788, 768), + intArrayOf(927, 787, 769), + intArrayOf(927, 788, 769), + intArrayOf(965, 787), + intArrayOf(965, 788), + intArrayOf(965, 787, 768), + intArrayOf(965, 788, 768), + intArrayOf(965, 787, 769), + intArrayOf(965, 788, 769), + intArrayOf(965, 787, 834), + intArrayOf(965, 788, 834), + intArrayOf(933, 788), + intArrayOf(933, 788, 768), + intArrayOf(933, 788, 769), + intArrayOf(933, 788, 834), + intArrayOf(969, 787), + intArrayOf(969, 788), + intArrayOf(969, 787, 768), + intArrayOf(969, 788, 768), + intArrayOf(969, 787, 769), + intArrayOf(969, 788, 769), + intArrayOf(969, 787, 834), + intArrayOf(969, 788, 834), + intArrayOf(937, 787), + intArrayOf(937, 788), + intArrayOf(937, 787, 768), + intArrayOf(937, 788, 768), + intArrayOf(937, 787, 769), + intArrayOf(937, 788, 769), + intArrayOf(937, 787, 834), + intArrayOf(937, 788, 834), + intArrayOf(945, 768), + intArrayOf(945, 769), + intArrayOf(949, 768), + intArrayOf(949, 769), + intArrayOf(951, 768), + intArrayOf(951, 769), + intArrayOf(953, 768), + intArrayOf(953, 769), + intArrayOf(959, 768), + intArrayOf(959, 769), + intArrayOf(965, 768), + intArrayOf(965, 769), + intArrayOf(969, 768), + intArrayOf(969, 769), + intArrayOf(945, 787, 837), + intArrayOf(945, 788, 837), + intArrayOf(945, 787, 768, 837), + intArrayOf(945, 788, 768, 837), + intArrayOf(945, 787, 769, 837), + intArrayOf(945, 788, 769, 837), + intArrayOf(945, 787, 834, 837), + intArrayOf(945, 788, 834, 837), + intArrayOf(913, 787, 837), + intArrayOf(913, 788, 837), + intArrayOf(913, 787, 768, 837), + intArrayOf(913, 788, 768, 837), + intArrayOf(913, 787, 769, 837), + intArrayOf(913, 788, 769, 837), + intArrayOf(913, 787, 834, 837), + intArrayOf(913, 788, 834, 837), + intArrayOf(951, 787, 837), + intArrayOf(951, 788, 837), + intArrayOf(951, 787, 768, 837), + intArrayOf(951, 788, 768, 837), + intArrayOf(951, 787, 769, 837), + intArrayOf(951, 788, 769, 837), + intArrayOf(951, 787, 834, 837), + intArrayOf(951, 788, 834, 837), + intArrayOf(919, 787, 837), + intArrayOf(919, 788, 837), + intArrayOf(919, 787, 768, 837), + intArrayOf(919, 788, 768, 837), + intArrayOf(919, 787, 769, 837), + intArrayOf(919, 788, 769, 837), + intArrayOf(919, 787, 834, 837), + intArrayOf(919, 788, 834, 837), + intArrayOf(969, 787, 837), + intArrayOf(969, 788, 837), + intArrayOf(969, 787, 768, 837), + intArrayOf(969, 788, 768, 837), + intArrayOf(969, 787, 769, 837), + intArrayOf(969, 788, 769, 837), + intArrayOf(969, 787, 834, 837), + intArrayOf(969, 788, 834, 837), + intArrayOf(937, 787, 837), + intArrayOf(937, 788, 837), + intArrayOf(937, 787, 768, 837), + intArrayOf(937, 788, 768, 837), + intArrayOf(937, 787, 769, 837), + intArrayOf(937, 788, 769, 837), + intArrayOf(937, 787, 834, 837), + intArrayOf(937, 788, 834, 837), + intArrayOf(945, 774), + intArrayOf(945, 772), + intArrayOf(945, 768, 837), + intArrayOf(945, 837), + intArrayOf(945, 769, 837), + intArrayOf(945, 834), + intArrayOf(945, 834, 837), + intArrayOf(913, 774), + intArrayOf(913, 772), + intArrayOf(913, 768), + intArrayOf(913, 769), + intArrayOf(913, 837), + intArrayOf(953), + intArrayOf(168, 834), + intArrayOf(951, 768, 837), + intArrayOf(951, 837), + intArrayOf(951, 769, 837), + intArrayOf(951, 834), + intArrayOf(951, 834, 837), + intArrayOf(917, 768), + intArrayOf(917, 769), + intArrayOf(919, 768), + intArrayOf(919, 769), + intArrayOf(919, 837), + intArrayOf(8127, 768), + intArrayOf(8127, 769), + intArrayOf(8127, 834), + intArrayOf(953, 774), + intArrayOf(953, 772), + intArrayOf(953, 776, 768), + intArrayOf(953, 776, 769), + intArrayOf(953, 834), + intArrayOf(953, 776, 834), + intArrayOf(921, 774), + intArrayOf(921, 772), + intArrayOf(921, 768), + intArrayOf(921, 769), + intArrayOf(8190, 768), + intArrayOf(8190, 769), + intArrayOf(8190, 834), + intArrayOf(965, 774), + intArrayOf(965, 772), + intArrayOf(965, 776, 768), + intArrayOf(965, 776, 769), + intArrayOf(961, 787), + intArrayOf(961, 788), + intArrayOf(965, 834), + intArrayOf(965, 776, 834), + intArrayOf(933, 774), + intArrayOf(933, 772), + intArrayOf(933, 768), + intArrayOf(933, 769), + intArrayOf(929, 788), + intArrayOf(168, 768), + intArrayOf(168, 769), + intArrayOf(96), + intArrayOf(969, 768, 837), + intArrayOf(969, 837), + intArrayOf(969, 769, 837), + intArrayOf(969, 834), + intArrayOf(969, 834, 837), + intArrayOf(927, 768), + intArrayOf(927, 769), + intArrayOf(937, 768), + intArrayOf(937, 769), + intArrayOf(937, 837), + intArrayOf(180), + intArrayOf(8194), + intArrayOf(8195), + intArrayOf(937), + intArrayOf(75), + intArrayOf(65, 778), + intArrayOf(8592, 824), + intArrayOf(8594, 824), + intArrayOf(8596, 824), + intArrayOf(8656, 824), + intArrayOf(8660, 824), + intArrayOf(8658, 824), + intArrayOf(8707, 824), + intArrayOf(8712, 824), + intArrayOf(8715, 824), + intArrayOf(8739, 824), + intArrayOf(8741, 824), + intArrayOf(8764, 824), + intArrayOf(8771, 824), + intArrayOf(8773, 824), + intArrayOf(8776, 824), + intArrayOf(61, 824), + intArrayOf(8801, 824), + intArrayOf(8781, 824), + intArrayOf(60, 824), + intArrayOf(62, 824), + intArrayOf(8804, 824), + intArrayOf(8805, 824), + intArrayOf(8818, 824), + intArrayOf(8819, 824), + intArrayOf(8822, 824), + intArrayOf(8823, 824), + intArrayOf(8826, 824), + intArrayOf(8827, 824), + intArrayOf(8834, 824), + intArrayOf(8835, 824), + intArrayOf(8838, 824), + intArrayOf(8839, 824), + intArrayOf(8866, 824), + intArrayOf(8872, 824), + intArrayOf(8873, 824), + intArrayOf(8875, 824), + intArrayOf(8828, 824), + intArrayOf(8829, 824), + intArrayOf(8849, 824), + intArrayOf(8850, 824), + intArrayOf(8882, 824), + intArrayOf(8883, 824), + intArrayOf(8884, 824), + intArrayOf(8885, 824), + intArrayOf(12296), + intArrayOf(12297), + intArrayOf(10973, 824), + intArrayOf(12363, 12441), + intArrayOf(12365, 12441), + intArrayOf(12367, 12441), + intArrayOf(12369, 12441), + intArrayOf(12371, 12441), + intArrayOf(12373, 12441), + intArrayOf(12375, 12441), + intArrayOf(12377, 12441), + intArrayOf(12379, 12441), + intArrayOf(12381, 12441), + intArrayOf(12383, 12441), + intArrayOf(12385, 12441), + intArrayOf(12388, 12441), + intArrayOf(12390, 12441), + intArrayOf(12392, 12441), + intArrayOf(12399, 12441), + intArrayOf(12399, 12442), + intArrayOf(12402, 12441), + intArrayOf(12402, 12442), + intArrayOf(12405, 12441), + intArrayOf(12405, 12442), + intArrayOf(12408, 12441), + intArrayOf(12408, 12442), + intArrayOf(12411, 12441), + intArrayOf(12411, 12442), + intArrayOf(12358, 12441), + intArrayOf(12445, 12441), + intArrayOf(12459, 12441), + intArrayOf(12461, 12441), + intArrayOf(12463, 12441), + intArrayOf(12465, 12441), + intArrayOf(12467, 12441), + intArrayOf(12469, 12441), + intArrayOf(12471, 12441), + intArrayOf(12473, 12441), + intArrayOf(12475, 12441), + intArrayOf(12477, 12441), + intArrayOf(12479, 12441), + intArrayOf(12481, 12441), + intArrayOf(12484, 12441), + intArrayOf(12486, 12441), + intArrayOf(12488, 12441), + intArrayOf(12495, 12441), + intArrayOf(12495, 12442), + intArrayOf(12498, 12441), + intArrayOf(12498, 12442), + intArrayOf(12501, 12441), + intArrayOf(12501, 12442), + intArrayOf(12504, 12441), + intArrayOf(12504, 12442), + intArrayOf(12507, 12441), + intArrayOf(12507, 12442), + intArrayOf(12454, 12441), + intArrayOf(12527, 12441), + intArrayOf(12528, 12441), + intArrayOf(12529, 12441), + intArrayOf(12530, 12441), + intArrayOf(12541, 12441), + intArrayOf(35912), + intArrayOf(26356), + intArrayOf(36554), + intArrayOf(36040), + intArrayOf(28369), + intArrayOf(20018), + intArrayOf(21477), + intArrayOf(40860), + intArrayOf(40860), + intArrayOf(22865), + intArrayOf(37329), + intArrayOf(21895), + intArrayOf(22856), + intArrayOf(25078), + intArrayOf(30313), + intArrayOf(32645), + intArrayOf(34367), + intArrayOf(34746), + intArrayOf(35064), + intArrayOf(37007), + intArrayOf(27138), + intArrayOf(27931), + intArrayOf(28889), + intArrayOf(29662), + intArrayOf(33853), + intArrayOf(37226), + intArrayOf(39409), + intArrayOf(20098), + intArrayOf(21365), + intArrayOf(27396), + intArrayOf(29211), + intArrayOf(34349), + intArrayOf(40478), + intArrayOf(23888), + intArrayOf(28651), + intArrayOf(34253), + intArrayOf(35172), + intArrayOf(25289), + intArrayOf(33240), + intArrayOf(34847), + intArrayOf(24266), + intArrayOf(26391), + intArrayOf(28010), + intArrayOf(29436), + intArrayOf(37070), + intArrayOf(20358), + intArrayOf(20919), + intArrayOf(21214), + intArrayOf(25796), + intArrayOf(27347), + intArrayOf(29200), + intArrayOf(30439), + intArrayOf(32769), + intArrayOf(34310), + intArrayOf(34396), + intArrayOf(36335), + intArrayOf(38706), + intArrayOf(39791), + intArrayOf(40442), + intArrayOf(30860), + intArrayOf(31103), + intArrayOf(32160), + intArrayOf(33737), + intArrayOf(37636), + intArrayOf(40575), + intArrayOf(35542), + intArrayOf(22751), + intArrayOf(24324), + intArrayOf(31840), + intArrayOf(32894), + intArrayOf(29282), + intArrayOf(30922), + intArrayOf(36034), + intArrayOf(38647), + intArrayOf(22744), + intArrayOf(23650), + intArrayOf(27155), + intArrayOf(28122), + intArrayOf(28431), + intArrayOf(32047), + intArrayOf(32311), + intArrayOf(38475), + intArrayOf(21202), + intArrayOf(32907), + intArrayOf(20956), + intArrayOf(20940), + intArrayOf(31260), + intArrayOf(32190), + intArrayOf(33777), + intArrayOf(38517), + intArrayOf(35712), + intArrayOf(25295), + intArrayOf(27138), + intArrayOf(35582), + intArrayOf(20025), + intArrayOf(23527), + intArrayOf(24594), + intArrayOf(29575), + intArrayOf(30064), + intArrayOf(21271), + intArrayOf(30971), + intArrayOf(20415), + intArrayOf(24489), + intArrayOf(19981), + intArrayOf(27852), + intArrayOf(25976), + intArrayOf(32034), + intArrayOf(21443), + intArrayOf(22622), + intArrayOf(30465), + intArrayOf(33865), + intArrayOf(35498), + intArrayOf(27578), + intArrayOf(36784), + intArrayOf(27784), + intArrayOf(25342), + intArrayOf(33509), + intArrayOf(25504), + intArrayOf(30053), + intArrayOf(20142), + intArrayOf(20841), + intArrayOf(20937), + intArrayOf(26753), + intArrayOf(31975), + intArrayOf(33391), + intArrayOf(35538), + intArrayOf(37327), + intArrayOf(21237), + intArrayOf(21570), + intArrayOf(22899), + intArrayOf(24300), + intArrayOf(26053), + intArrayOf(28670), + intArrayOf(31018), + intArrayOf(38317), + intArrayOf(39530), + intArrayOf(40599), + intArrayOf(40654), + intArrayOf(21147), + intArrayOf(26310), + intArrayOf(27511), + intArrayOf(36706), + intArrayOf(24180), + intArrayOf(24976), + intArrayOf(25088), + intArrayOf(25754), + intArrayOf(28451), + intArrayOf(29001), + intArrayOf(29833), + intArrayOf(31178), + intArrayOf(32244), + intArrayOf(32879), + intArrayOf(36646), + intArrayOf(34030), + intArrayOf(36899), + intArrayOf(37706), + intArrayOf(21015), + intArrayOf(21155), + intArrayOf(21693), + intArrayOf(28872), + intArrayOf(35010), + intArrayOf(35498), + intArrayOf(24265), + intArrayOf(24565), + intArrayOf(25467), + intArrayOf(27566), + intArrayOf(31806), + intArrayOf(29557), + intArrayOf(20196), + intArrayOf(22265), + intArrayOf(23527), + intArrayOf(23994), + intArrayOf(24604), + intArrayOf(29618), + intArrayOf(29801), + intArrayOf(32666), + intArrayOf(32838), + intArrayOf(37428), + intArrayOf(38646), + intArrayOf(38728), + intArrayOf(38936), + intArrayOf(20363), + intArrayOf(31150), + intArrayOf(37300), + intArrayOf(38584), + intArrayOf(24801), + intArrayOf(20102), + intArrayOf(20698), + intArrayOf(23534), + intArrayOf(23615), + intArrayOf(26009), + intArrayOf(27138), + intArrayOf(29134), + intArrayOf(30274), + intArrayOf(34044), + intArrayOf(36988), + intArrayOf(40845), + intArrayOf(26248), + intArrayOf(38446), + intArrayOf(21129), + intArrayOf(26491), + intArrayOf(26611), + intArrayOf(27969), + intArrayOf(28316), + intArrayOf(29705), + intArrayOf(30041), + intArrayOf(30827), + intArrayOf(32016), + intArrayOf(39006), + intArrayOf(20845), + intArrayOf(25134), + intArrayOf(38520), + intArrayOf(20523), + intArrayOf(23833), + intArrayOf(28138), + intArrayOf(36650), + intArrayOf(24459), + intArrayOf(24900), + intArrayOf(26647), + intArrayOf(29575), + intArrayOf(38534), + intArrayOf(21033), + intArrayOf(21519), + intArrayOf(23653), + intArrayOf(26131), + intArrayOf(26446), + intArrayOf(26792), + intArrayOf(27877), + intArrayOf(29702), + intArrayOf(30178), + intArrayOf(32633), + intArrayOf(35023), + intArrayOf(35041), + intArrayOf(37324), + intArrayOf(38626), + intArrayOf(21311), + intArrayOf(28346), + intArrayOf(21533), + intArrayOf(29136), + intArrayOf(29848), + intArrayOf(34298), + intArrayOf(38563), + intArrayOf(40023), + intArrayOf(40607), + intArrayOf(26519), + intArrayOf(28107), + intArrayOf(33256), + intArrayOf(31435), + intArrayOf(31520), + intArrayOf(31890), + intArrayOf(29376), + intArrayOf(28825), + intArrayOf(35672), + intArrayOf(20160), + intArrayOf(33590), + intArrayOf(21050), + intArrayOf(20999), + intArrayOf(24230), + intArrayOf(25299), + intArrayOf(31958), + intArrayOf(23429), + intArrayOf(27934), + intArrayOf(26292), + intArrayOf(36667), + intArrayOf(34892), + intArrayOf(38477), + intArrayOf(35211), + intArrayOf(24275), + intArrayOf(20800), + intArrayOf(21952), + intArrayOf(22618), + intArrayOf(26228), + intArrayOf(20958), + intArrayOf(29482), + intArrayOf(30410), + intArrayOf(31036), + intArrayOf(31070), + intArrayOf(31077), + intArrayOf(31119), + intArrayOf(38742), + intArrayOf(31934), + intArrayOf(32701), + intArrayOf(34322), + intArrayOf(35576), + intArrayOf(36920), + intArrayOf(37117), + intArrayOf(39151), + intArrayOf(39164), + intArrayOf(39208), + intArrayOf(40372), + intArrayOf(20398), + intArrayOf(20711), + intArrayOf(20813), + intArrayOf(21193), + intArrayOf(21220), + intArrayOf(21329), + intArrayOf(21917), + intArrayOf(22022), + intArrayOf(22120), + intArrayOf(22592), + intArrayOf(22696), + intArrayOf(23652), + intArrayOf(23662), + intArrayOf(24724), + intArrayOf(24936), + intArrayOf(24974), + intArrayOf(25074), + intArrayOf(25935), + intArrayOf(26082), + intArrayOf(26257), + intArrayOf(26757), + intArrayOf(28023), + intArrayOf(28186), + intArrayOf(28450), + intArrayOf(29038), + intArrayOf(29227), + intArrayOf(29730), + intArrayOf(30865), + intArrayOf(31038), + intArrayOf(31049), + intArrayOf(31048), + intArrayOf(31056), + intArrayOf(31062), + intArrayOf(31069), + intArrayOf(31117), + intArrayOf(31118), + intArrayOf(31296), + intArrayOf(31361), + intArrayOf(31680), + intArrayOf(32244), + intArrayOf(32265), + intArrayOf(32321), + intArrayOf(32626), + intArrayOf(32773), + intArrayOf(33261), + intArrayOf(33401), + intArrayOf(33401), + intArrayOf(33879), + intArrayOf(35088), + intArrayOf(35222), + intArrayOf(35585), + intArrayOf(35641), + intArrayOf(36051), + intArrayOf(36104), + intArrayOf(36790), + intArrayOf(36920), + intArrayOf(38627), + intArrayOf(38911), + intArrayOf(38971), + intArrayOf(20006), + intArrayOf(20917), + intArrayOf(20840), + intArrayOf(20352), + intArrayOf(20805), + intArrayOf(20864), + intArrayOf(21191), + intArrayOf(21242), + intArrayOf(21917), + intArrayOf(21845), + intArrayOf(21913), + intArrayOf(21986), + intArrayOf(22618), + intArrayOf(22707), + intArrayOf(22852), + intArrayOf(22868), + intArrayOf(23138), + intArrayOf(23336), + intArrayOf(24274), + intArrayOf(24281), + intArrayOf(24425), + intArrayOf(24493), + intArrayOf(24792), + intArrayOf(24910), + intArrayOf(24840), + intArrayOf(24974), + intArrayOf(24928), + intArrayOf(25074), + intArrayOf(25140), + intArrayOf(25540), + intArrayOf(25628), + intArrayOf(25682), + intArrayOf(25942), + intArrayOf(26228), + intArrayOf(26391), + intArrayOf(26395), + intArrayOf(26454), + intArrayOf(27513), + intArrayOf(27578), + intArrayOf(27969), + intArrayOf(28379), + intArrayOf(28363), + intArrayOf(28450), + intArrayOf(28702), + intArrayOf(29038), + intArrayOf(30631), + intArrayOf(29237), + intArrayOf(29359), + intArrayOf(29482), + intArrayOf(29809), + intArrayOf(29958), + intArrayOf(30011), + intArrayOf(30237), + intArrayOf(30239), + intArrayOf(30410), + intArrayOf(30427), + intArrayOf(30452), + intArrayOf(30538), + intArrayOf(30528), + intArrayOf(30924), + intArrayOf(31409), + intArrayOf(31680), + intArrayOf(31867), + intArrayOf(32091), + intArrayOf(32244), + intArrayOf(32574), + intArrayOf(32773), + intArrayOf(33618), + intArrayOf(33775), + intArrayOf(34681), + intArrayOf(35137), + intArrayOf(35206), + intArrayOf(35222), + intArrayOf(35519), + intArrayOf(35576), + intArrayOf(35531), + intArrayOf(35585), + intArrayOf(35582), + intArrayOf(35565), + intArrayOf(35641), + intArrayOf(35722), + intArrayOf(36104), + intArrayOf(36664), + intArrayOf(36978), + intArrayOf(37273), + intArrayOf(37494), + intArrayOf(38524), + intArrayOf(38627), + intArrayOf(38742), + intArrayOf(38875), + intArrayOf(38911), + intArrayOf(38923), + intArrayOf(38971), + intArrayOf(39698), + intArrayOf(40860), + intArrayOf(141386), + intArrayOf(141380), + intArrayOf(144341), + intArrayOf(15261), + intArrayOf(16408), + intArrayOf(16441), + intArrayOf(152137), + intArrayOf(154832), + intArrayOf(163539), + intArrayOf(40771), + intArrayOf(40846), + intArrayOf(1497, 1460), + intArrayOf(1522, 1463), + intArrayOf(1513, 1473), + intArrayOf(1513, 1474), + intArrayOf(1513, 1468, 1473), + intArrayOf(1513, 1468, 1474), + intArrayOf(1488, 1463), + intArrayOf(1488, 1464), + intArrayOf(1488, 1468), + intArrayOf(1489, 1468), + intArrayOf(1490, 1468), + intArrayOf(1491, 1468), + intArrayOf(1492, 1468), + intArrayOf(1493, 1468), + intArrayOf(1494, 1468), + intArrayOf(1496, 1468), + intArrayOf(1497, 1468), + intArrayOf(1498, 1468), + intArrayOf(1499, 1468), + intArrayOf(1500, 1468), + intArrayOf(1502, 1468), + intArrayOf(1504, 1468), + intArrayOf(1505, 1468), + intArrayOf(1507, 1468), + intArrayOf(1508, 1468), + intArrayOf(1510, 1468), + intArrayOf(1511, 1468), + intArrayOf(1512, 1468), + intArrayOf(1513, 1468), + intArrayOf(1514, 1468), + intArrayOf(1493, 1465), + intArrayOf(1489, 1471), + intArrayOf(1499, 1471), + intArrayOf(1508, 1471), + intArrayOf(119127, 119141), + intArrayOf(119128, 119141), + intArrayOf(119128, 119141, 119150), + intArrayOf(119128, 119141, 119151), + intArrayOf(119128, 119141, 119152), + intArrayOf(119128, 119141, 119153), + intArrayOf(119128, 119141, 119154), + intArrayOf(119225, 119141), + intArrayOf(119226, 119141), + intArrayOf(119225, 119141, 119150), + intArrayOf(119226, 119141, 119150), + intArrayOf(119225, 119141, 119151), + intArrayOf(119226, 119141, 119151), + intArrayOf(20029), + intArrayOf(20024), + intArrayOf(20033), + intArrayOf(131362), + intArrayOf(20320), + intArrayOf(20398), + intArrayOf(20411), + intArrayOf(20482), + intArrayOf(20602), + intArrayOf(20633), + intArrayOf(20711), + intArrayOf(20687), + intArrayOf(13470), + intArrayOf(132666), + intArrayOf(20813), + intArrayOf(20820), + intArrayOf(20836), + intArrayOf(20855), + intArrayOf(132380), + intArrayOf(13497), + intArrayOf(20839), + intArrayOf(20877), + intArrayOf(132427), + intArrayOf(20887), + intArrayOf(20900), + intArrayOf(20172), + intArrayOf(20908), + intArrayOf(20917), + intArrayOf(168415), + intArrayOf(20981), + intArrayOf(20995), + intArrayOf(13535), + intArrayOf(21051), + intArrayOf(21062), + intArrayOf(21106), + intArrayOf(21111), + intArrayOf(13589), + intArrayOf(21191), + intArrayOf(21193), + intArrayOf(21220), + intArrayOf(21242), + intArrayOf(21253), + intArrayOf(21254), + intArrayOf(21271), + intArrayOf(21321), + intArrayOf(21329), + intArrayOf(21338), + intArrayOf(21363), + intArrayOf(21373), + intArrayOf(21375), + intArrayOf(21375), + intArrayOf(21375), + intArrayOf(133676), + intArrayOf(28784), + intArrayOf(21450), + intArrayOf(21471), + intArrayOf(133987), + intArrayOf(21483), + intArrayOf(21489), + intArrayOf(21510), + intArrayOf(21662), + intArrayOf(21560), + intArrayOf(21576), + intArrayOf(21608), + intArrayOf(21666), + intArrayOf(21750), + intArrayOf(21776), + intArrayOf(21843), + intArrayOf(21859), + intArrayOf(21892), + intArrayOf(21892), + intArrayOf(21913), + intArrayOf(21931), + intArrayOf(21939), + intArrayOf(21954), + intArrayOf(22294), + intArrayOf(22022), + intArrayOf(22295), + intArrayOf(22097), + intArrayOf(22132), + intArrayOf(20999), + intArrayOf(22766), + intArrayOf(22478), + intArrayOf(22516), + intArrayOf(22541), + intArrayOf(22411), + intArrayOf(22578), + intArrayOf(22577), + intArrayOf(22700), + intArrayOf(136420), + intArrayOf(22770), + intArrayOf(22775), + intArrayOf(22790), + intArrayOf(22810), + intArrayOf(22818), + intArrayOf(22882), + intArrayOf(136872), + intArrayOf(136938), + intArrayOf(23020), + intArrayOf(23067), + intArrayOf(23079), + intArrayOf(23000), + intArrayOf(23142), + intArrayOf(14062), + intArrayOf(14076), + intArrayOf(23304), + intArrayOf(23358), + intArrayOf(23358), + intArrayOf(137672), + intArrayOf(23491), + intArrayOf(23512), + intArrayOf(23527), + intArrayOf(23539), + intArrayOf(138008), + intArrayOf(23551), + intArrayOf(23558), + intArrayOf(24403), + intArrayOf(23586), + intArrayOf(14209), + intArrayOf(23648), + intArrayOf(23662), + intArrayOf(23744), + intArrayOf(23693), + intArrayOf(138724), + intArrayOf(23875), + intArrayOf(138726), + intArrayOf(23918), + intArrayOf(23915), + intArrayOf(23932), + intArrayOf(24033), + intArrayOf(24034), + intArrayOf(14383), + intArrayOf(24061), + intArrayOf(24104), + intArrayOf(24125), + intArrayOf(24169), + intArrayOf(14434), + intArrayOf(139651), + intArrayOf(14460), + intArrayOf(24240), + intArrayOf(24243), + intArrayOf(24246), + intArrayOf(24266), + intArrayOf(172946), + intArrayOf(24318), + intArrayOf(140081), + intArrayOf(140081), + intArrayOf(33281), + intArrayOf(24354), + intArrayOf(24354), + intArrayOf(14535), + intArrayOf(144056), + intArrayOf(156122), + intArrayOf(24418), + intArrayOf(24427), + intArrayOf(14563), + intArrayOf(24474), + intArrayOf(24525), + intArrayOf(24535), + intArrayOf(24569), + intArrayOf(24705), + intArrayOf(14650), + intArrayOf(14620), + intArrayOf(24724), + intArrayOf(141012), + intArrayOf(24775), + intArrayOf(24904), + intArrayOf(24908), + intArrayOf(24910), + intArrayOf(24908), + intArrayOf(24954), + intArrayOf(24974), + intArrayOf(25010), + intArrayOf(24996), + intArrayOf(25007), + intArrayOf(25054), + intArrayOf(25074), + intArrayOf(25078), + intArrayOf(25104), + intArrayOf(25115), + intArrayOf(25181), + intArrayOf(25265), + intArrayOf(25300), + intArrayOf(25424), + intArrayOf(142092), + intArrayOf(25405), + intArrayOf(25340), + intArrayOf(25448), + intArrayOf(25475), + intArrayOf(25572), + intArrayOf(142321), + intArrayOf(25634), + intArrayOf(25541), + intArrayOf(25513), + intArrayOf(14894), + intArrayOf(25705), + intArrayOf(25726), + intArrayOf(25757), + intArrayOf(25719), + intArrayOf(14956), + intArrayOf(25935), + intArrayOf(25964), + intArrayOf(143370), + intArrayOf(26083), + intArrayOf(26360), + intArrayOf(26185), + intArrayOf(15129), + intArrayOf(26257), + intArrayOf(15112), + intArrayOf(15076), + intArrayOf(20882), + intArrayOf(20885), + intArrayOf(26368), + intArrayOf(26268), + intArrayOf(32941), + intArrayOf(17369), + intArrayOf(26391), + intArrayOf(26395), + intArrayOf(26401), + intArrayOf(26462), + intArrayOf(26451), + intArrayOf(144323), + intArrayOf(15177), + intArrayOf(26618), + intArrayOf(26501), + intArrayOf(26706), + intArrayOf(26757), + intArrayOf(144493), + intArrayOf(26766), + intArrayOf(26655), + intArrayOf(26900), + intArrayOf(15261), + intArrayOf(26946), + intArrayOf(27043), + intArrayOf(27114), + intArrayOf(27304), + intArrayOf(145059), + intArrayOf(27355), + intArrayOf(15384), + intArrayOf(27425), + intArrayOf(145575), + intArrayOf(27476), + intArrayOf(15438), + intArrayOf(27506), + intArrayOf(27551), + intArrayOf(27578), + intArrayOf(27579), + intArrayOf(146061), + intArrayOf(138507), + intArrayOf(146170), + intArrayOf(27726), + intArrayOf(146620), + intArrayOf(27839), + intArrayOf(27853), + intArrayOf(27751), + intArrayOf(27926), + intArrayOf(27966), + intArrayOf(28023), + intArrayOf(27969), + intArrayOf(28009), + intArrayOf(28024), + intArrayOf(28037), + intArrayOf(146718), + intArrayOf(27956), + intArrayOf(28207), + intArrayOf(28270), + intArrayOf(15667), + intArrayOf(28363), + intArrayOf(28359), + intArrayOf(147153), + intArrayOf(28153), + intArrayOf(28526), + intArrayOf(147294), + intArrayOf(147342), + intArrayOf(28614), + intArrayOf(28729), + intArrayOf(28702), + intArrayOf(28699), + intArrayOf(15766), + intArrayOf(28746), + intArrayOf(28797), + intArrayOf(28791), + intArrayOf(28845), + intArrayOf(132389), + intArrayOf(28997), + intArrayOf(148067), + intArrayOf(29084), + intArrayOf(148395), + intArrayOf(29224), + intArrayOf(29237), + intArrayOf(29264), + intArrayOf(149000), + intArrayOf(29312), + intArrayOf(29333), + intArrayOf(149301), + intArrayOf(149524), + intArrayOf(29562), + intArrayOf(29579), + intArrayOf(16044), + intArrayOf(29605), + intArrayOf(16056), + intArrayOf(16056), + intArrayOf(29767), + intArrayOf(29788), + intArrayOf(29809), + intArrayOf(29829), + intArrayOf(29898), + intArrayOf(16155), + intArrayOf(29988), + intArrayOf(150582), + intArrayOf(30014), + intArrayOf(150674), + intArrayOf(30064), + intArrayOf(139679), + intArrayOf(30224), + intArrayOf(151457), + intArrayOf(151480), + intArrayOf(151620), + intArrayOf(16380), + intArrayOf(16392), + intArrayOf(30452), + intArrayOf(151795), + intArrayOf(151794), + intArrayOf(151833), + intArrayOf(151859), + intArrayOf(30494), + intArrayOf(30495), + intArrayOf(30495), + intArrayOf(30538), + intArrayOf(16441), + intArrayOf(30603), + intArrayOf(16454), + intArrayOf(16534), + intArrayOf(152605), + intArrayOf(30798), + intArrayOf(30860), + intArrayOf(30924), + intArrayOf(16611), + intArrayOf(153126), + intArrayOf(31062), + intArrayOf(153242), + intArrayOf(153285), + intArrayOf(31119), + intArrayOf(31211), + intArrayOf(16687), + intArrayOf(31296), + intArrayOf(31306), + intArrayOf(31311), + intArrayOf(153980), + intArrayOf(154279), + intArrayOf(154279), + intArrayOf(31470), + intArrayOf(16898), + intArrayOf(154539), + intArrayOf(31686), + intArrayOf(31689), + intArrayOf(16935), + intArrayOf(154752), + intArrayOf(31954), + intArrayOf(17056), + intArrayOf(31976), + intArrayOf(31971), + intArrayOf(32000), + intArrayOf(155526), + intArrayOf(32099), + intArrayOf(17153), + intArrayOf(32199), + intArrayOf(32258), + intArrayOf(32325), + intArrayOf(17204), + intArrayOf(156200), + intArrayOf(156231), + intArrayOf(17241), + intArrayOf(156377), + intArrayOf(32634), + intArrayOf(156478), + intArrayOf(32661), + intArrayOf(32762), + intArrayOf(32773), + intArrayOf(156890), + intArrayOf(156963), + intArrayOf(32864), + intArrayOf(157096), + intArrayOf(32880), + intArrayOf(144223), + intArrayOf(17365), + intArrayOf(32946), + intArrayOf(33027), + intArrayOf(17419), + intArrayOf(33086), + intArrayOf(23221), + intArrayOf(157607), + intArrayOf(157621), + intArrayOf(144275), + intArrayOf(144284), + intArrayOf(33281), + intArrayOf(33284), + intArrayOf(36766), + intArrayOf(17515), + intArrayOf(33425), + intArrayOf(33419), + intArrayOf(33437), + intArrayOf(21171), + intArrayOf(33457), + intArrayOf(33459), + intArrayOf(33469), + intArrayOf(33510), + intArrayOf(158524), + intArrayOf(33509), + intArrayOf(33565), + intArrayOf(33635), + intArrayOf(33709), + intArrayOf(33571), + intArrayOf(33725), + intArrayOf(33767), + intArrayOf(33879), + intArrayOf(33619), + intArrayOf(33738), + intArrayOf(33740), + intArrayOf(33756), + intArrayOf(158774), + intArrayOf(159083), + intArrayOf(158933), + intArrayOf(17707), + intArrayOf(34033), + intArrayOf(34035), + intArrayOf(34070), + intArrayOf(160714), + intArrayOf(34148), + intArrayOf(159532), + intArrayOf(17757), + intArrayOf(17761), + intArrayOf(159665), + intArrayOf(159954), + intArrayOf(17771), + intArrayOf(34384), + intArrayOf(34396), + intArrayOf(34407), + intArrayOf(34409), + intArrayOf(34473), + intArrayOf(34440), + intArrayOf(34574), + intArrayOf(34530), + intArrayOf(34681), + intArrayOf(34600), + intArrayOf(34667), + intArrayOf(34694), + intArrayOf(17879), + intArrayOf(34785), + intArrayOf(34817), + intArrayOf(17913), + intArrayOf(34912), + intArrayOf(34915), + intArrayOf(161383), + intArrayOf(35031), + intArrayOf(35038), + intArrayOf(17973), + intArrayOf(35066), + intArrayOf(13499), + intArrayOf(161966), + intArrayOf(162150), + intArrayOf(18110), + intArrayOf(18119), + intArrayOf(35488), + intArrayOf(35565), + intArrayOf(35722), + intArrayOf(35925), + intArrayOf(162984), + intArrayOf(36011), + intArrayOf(36033), + intArrayOf(36123), + intArrayOf(36215), + intArrayOf(163631), + intArrayOf(133124), + intArrayOf(36299), + intArrayOf(36284), + intArrayOf(36336), + intArrayOf(133342), + intArrayOf(36564), + intArrayOf(36664), + intArrayOf(165330), + intArrayOf(165357), + intArrayOf(37012), + intArrayOf(37105), + intArrayOf(37137), + intArrayOf(165678), + intArrayOf(37147), + intArrayOf(37432), + intArrayOf(37591), + intArrayOf(37592), + intArrayOf(37500), + intArrayOf(37881), + intArrayOf(37909), + intArrayOf(166906), + intArrayOf(38283), + intArrayOf(18837), + intArrayOf(38327), + intArrayOf(167287), + intArrayOf(18918), + intArrayOf(38595), + intArrayOf(23986), + intArrayOf(38691), + intArrayOf(168261), + intArrayOf(168474), + intArrayOf(19054), + intArrayOf(19062), + intArrayOf(38880), + intArrayOf(168970), + intArrayOf(19122), + intArrayOf(169110), + intArrayOf(38923), + intArrayOf(38923), + intArrayOf(38953), + intArrayOf(169398), + intArrayOf(39138), + intArrayOf(19251), + intArrayOf(39209), + intArrayOf(39335), + intArrayOf(39362), + intArrayOf(39422), + intArrayOf(19406), + intArrayOf(170800), + intArrayOf(39698), + intArrayOf(40000), + intArrayOf(40189), + intArrayOf(19662), + intArrayOf(19693), + intArrayOf(40295), + intArrayOf(172238), + intArrayOf(19704), + intArrayOf(172293), + intArrayOf(172558), + intArrayOf(172689), + intArrayOf(40635), + intArrayOf(19798), + intArrayOf(40697), + intArrayOf(40702), + intArrayOf(40709), + intArrayOf(40719), + intArrayOf(40726), + intArrayOf(40763), + intArrayOf(173568) +) \ No newline at end of file diff --git a/libraries/stdlib/wasm/stubs/native/concurrent.kt b/libraries/stdlib/wasm/stubs/native/concurrent.kt index 11ed4059bb3..183af955ce0 100644 --- a/libraries/stdlib/wasm/stubs/native/concurrent.kt +++ b/libraries/stdlib/wasm/stubs/native/concurrent.kt @@ -9,3 +9,23 @@ package kotlin.native.concurrent internal val Any?.isFrozen inline get() = false + +internal inline fun T.freeze(): T = this + +internal class AtomicReference(public var value: T) { + public fun compareAndSwap(expected: T, new: T): T { + if (value == expected) { + val old = value + value = new + return old + } + return value + } + public fun compareAndSet(expected: T, new: T): Boolean { + if (value == expected) { + value = new + return true + } + return false + } +} diff --git a/libraries/stdlib/wasm/test/testUtils.kt b/libraries/stdlib/wasm/test/testUtils.kt index 3f58fa4ef83..5c787894183 100644 --- a/libraries/stdlib/wasm/test/testUtils.kt +++ b/libraries/stdlib/wasm/test/testUtils.kt @@ -32,4 +32,4 @@ actual val supportsSuppressedExceptions: Boolean get() = false // TODO: implement named group reference in replacement expression public actual val supportsNamedCapturingGroup: Boolean get() = false -public actual val regexSplitUnicodeCodePointHandling: Boolean get() = TODO() \ No newline at end of file +public actual val regexSplitUnicodeCodePointHandling: Boolean get() = true \ No newline at end of file