stdlib: Add StringBuilder.reverse method

This commit is contained in:
Ilya Matveev
2017-04-19 11:43:03 +07:00
committed by ilmat192
parent 5517ed7296
commit f9c6b6e6e4
3 changed files with 130 additions and 0 deletions
+5
View File
@@ -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)