stdlib: Add StringBuilder.reverse method
This commit is contained in:
@@ -1080,6 +1080,11 @@ task string_builder0(type: RunKonanTest) {
|
||||
source = "runtime/text/string_builder0.kt"
|
||||
}
|
||||
|
||||
task string_builder_reverse(type: RunKonanTest) {
|
||||
goldValue = "OK\n"
|
||||
source = "runtime/text/string_builder_reverse.kt"
|
||||
}
|
||||
|
||||
task string0(type: RunKonanTest) {
|
||||
goldValue = "true\ntrue\nПРИВЕТ\nпривет\nПока\ntrue\n"
|
||||
source = "runtime/text/string0.kt"
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
fun assertEquals(builder: StringBuilder, content: String) {
|
||||
if (builder.toString() != content) throw AssertionError("Test failed: $builder != $content")
|
||||
}
|
||||
|
||||
fun assertTrue(condition: Boolean) {
|
||||
if (!condition) throw AssertionError("The condition is false")
|
||||
}
|
||||
|
||||
fun reverseTest(original: String, reversed: String, reversedBack: String) {
|
||||
assertEquals(StringBuilder(original).reverse(), reversed)
|
||||
assertEquals(StringBuilder(reversed).reverse(), reversedBack)
|
||||
}
|
||||
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
var builder = StringBuilder("123456")
|
||||
assertTrue(builder === builder.reverse())
|
||||
assertEquals(builder, "654321")
|
||||
|
||||
builder.length = 1
|
||||
assertEquals(builder, "6")
|
||||
|
||||
builder.length = 0
|
||||
assertEquals(builder, "")
|
||||
|
||||
var str: String = "a"
|
||||
reverseTest(str, str, str)
|
||||
|
||||
str = "ab"
|
||||
reverseTest(str, "ba", str)
|
||||
|
||||
str = "abcdef"
|
||||
reverseTest(str, "fedcba", str)
|
||||
|
||||
str = "abcdefg"
|
||||
reverseTest(str, "gfedcba", str)
|
||||
|
||||
str = "\ud800\udc00"
|
||||
reverseTest(str, str, str)
|
||||
|
||||
str = "\udc00\ud800"
|
||||
reverseTest(str, "\ud800\udc00", "\ud800\udc00")
|
||||
|
||||
str = "a\ud800\udc00"
|
||||
reverseTest(str, "\ud800\udc00a", str)
|
||||
|
||||
str = "ab\ud800\udc00"
|
||||
reverseTest(str, "\ud800\udc00ba", str)
|
||||
|
||||
str = "abc\ud800\udc00"
|
||||
reverseTest(str, "\ud800\udc00cba", str)
|
||||
|
||||
str = "\ud800\udc00\udc01\ud801\ud802\udc02"
|
||||
reverseTest(str, "\ud802\udc02\ud801\udc01\ud800\udc00",
|
||||
"\ud800\udc00\ud801\udc01\ud802\udc02")
|
||||
|
||||
str = "\ud800\udc00\ud801\udc01\ud802\udc02"
|
||||
reverseTest(str, "\ud802\udc02\ud801\udc01\ud800\udc00", str)
|
||||
|
||||
str = "\ud800\udc00\udc01\ud801a"
|
||||
reverseTest(str, "a\ud801\udc01\ud800\udc00",
|
||||
"\ud800\udc00\ud801\udc01a")
|
||||
|
||||
str = "a\ud800\udc00\ud801\udc01"
|
||||
reverseTest(str, "\ud801\udc01\ud800\udc00a", str)
|
||||
|
||||
str = "\ud800\udc00\udc01\ud801ab"
|
||||
reverseTest(str, "ba\ud801\udc01\ud800\udc00",
|
||||
"\ud800\udc00\ud801\udc01ab")
|
||||
|
||||
str = "ab\ud800\udc00\ud801\udc01"
|
||||
reverseTest(str, "\ud801\udc01\ud800\udc00ba", str)
|
||||
|
||||
str = "\ud800\udc00\ud801\udc01"
|
||||
reverseTest(str, "\ud801\udc01\ud800\udc00", str)
|
||||
|
||||
str = "a\ud800\udc00z\ud801\udc01"
|
||||
reverseTest(str, "\ud801\udc01z\ud800\udc00a", str)
|
||||
|
||||
str = "a\ud800\udc00bz\ud801\udc01"
|
||||
reverseTest(str, "\ud801\udc01zb\ud800\udc00a", str)
|
||||
|
||||
str = "abc\ud802\udc02\ud801\udc01\ud800\udc00"
|
||||
reverseTest(str, "\ud800\udc00\ud801\udc01\ud802\udc02cba", str)
|
||||
|
||||
str = "abcd\ud802\udc02\ud801\udc01\ud800\udc00"
|
||||
reverseTest(str, "\ud800\udc00\ud801\udc01\ud802\udc02dcba", str)
|
||||
|
||||
println("OK")
|
||||
}
|
||||
@@ -40,6 +40,10 @@ class StringBuilder private constructor (
|
||||
length = array.size
|
||||
}
|
||||
|
||||
constructor(sequence: CharSequence): this(sequence.length) {
|
||||
append(sequence)
|
||||
}
|
||||
|
||||
override var length: Int = 0
|
||||
set(capacity) {
|
||||
ensureCapacity(capacity)
|
||||
@@ -75,6 +79,37 @@ class StringBuilder private constructor (
|
||||
}
|
||||
}
|
||||
|
||||
fun reverse(): StringBuilder {
|
||||
var front = 0
|
||||
var end = array.lastIndex
|
||||
var hasSurrogates = false
|
||||
while (front < end) {
|
||||
if (array[front].isSurrogate() || array[end].isSurrogate()) {
|
||||
hasSurrogates = true
|
||||
}
|
||||
val tmp = array[front]
|
||||
array[front] = array[end]
|
||||
array[end] = tmp
|
||||
front++
|
||||
end--
|
||||
}
|
||||
|
||||
// Reverse surrogate pairs back.
|
||||
if (hasSurrogates) {
|
||||
var i = 0
|
||||
while (i < length - 1) {
|
||||
if (array[i].isLowSurrogate() && array[i + 1].isHighSurrogate()) {
|
||||
val tmp = array[i]
|
||||
array[i] = array[i + 1]
|
||||
array[i + 1] = tmp
|
||||
i++
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
// Of Appenable.
|
||||
override fun append(c: Char) : StringBuilder {
|
||||
ensureExtraCapacity(1)
|
||||
|
||||
Reference in New Issue
Block a user