aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strings
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-03-30 15:33:16 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-03-30 15:33:16 +0000
commitf72f4169133572cf62f1e872c5657cdbc4d5de2c (patch)
tree9382d76e5dc68294cdf3c4f2c03a9f61b44fb014 /libgo/go/strings
parentf2034d064c29d9620c5562b2b5b517bdc6c7a672 (diff)
downloadgcc-f72f4169133572cf62f1e872c5657cdbc4d5de2c.zip
gcc-f72f4169133572cf62f1e872c5657cdbc4d5de2c.tar.gz
gcc-f72f4169133572cf62f1e872c5657cdbc4d5de2c.tar.bz2
Update to current Go library.
From-SVN: r171732
Diffstat (limited to 'libgo/go/strings')
-rw-r--r--libgo/go/strings/strings.go35
-rw-r--r--libgo/go/strings/strings_test.go32
2 files changed, 48 insertions, 19 deletions
diff --git a/libgo/go/strings/strings.go b/libgo/go/strings/strings.go
index 5f009e5..93c7c46 100644
--- a/libgo/go/strings/strings.go
+++ b/libgo/go/strings/strings.go
@@ -275,20 +275,10 @@ func Join(a []string, sep string) string {
}
b := make([]byte, n)
- bp := 0
- for i := 0; i < len(a); i++ {
- s := a[i]
- for j := 0; j < len(s); j++ {
- b[bp] = s[j]
- bp++
- }
- if i+1 < len(a) {
- s = sep
- for j := 0; j < len(s); j++ {
- b[bp] = s[j]
- bp++
- }
- }
+ bp := copy(b, a[0])
+ for _, s := range a[1:] {
+ bp += copy(b[bp:], sep)
+ bp += copy(b[bp:], s)
}
return string(b)
}
@@ -312,9 +302,19 @@ func Map(mapping func(rune int) int, s string) string {
// fine. It could also shrink but that falls out naturally.
maxbytes := len(s) // length of b
nbytes := 0 // number of bytes encoded in b
- b := make([]byte, maxbytes)
- for _, c := range s {
+ // The output buffer b is initialized on demand, the first
+ // time a character differs.
+ var b []byte
+
+ for i, c := range s {
rune := mapping(c)
+ if b == nil {
+ if rune == c {
+ continue
+ }
+ b = make([]byte, maxbytes)
+ nbytes = copy(b, s[:i])
+ }
if rune >= 0 {
wid := 1
if rune >= utf8.RuneSelf {
@@ -330,6 +330,9 @@ func Map(mapping func(rune int) int, s string) string {
nbytes += utf8.EncodeRune(b[nbytes:maxbytes], rune)
}
}
+ if b == nil {
+ return s
+ }
return string(b[0:nbytes])
}
diff --git a/libgo/go/strings/strings_test.go b/libgo/go/strings/strings_test.go
index 41e3987..c45b148 100644
--- a/libgo/go/strings/strings_test.go
+++ b/libgo/go/strings/strings_test.go
@@ -6,10 +6,12 @@ package strings_test
import (
"os"
+ "reflect"
"strconv"
. "strings"
"testing"
"unicode"
+ "unsafe"
"utf8"
)
@@ -429,12 +431,32 @@ func TestMap(t *testing.T) {
if m != expect {
t.Errorf("drop: expected %q got %q", expect, m)
}
+
+ // 6. Identity
+ identity := func(rune int) int {
+ return rune
+ }
+ orig := "Input string that we expect not to be copied."
+ m = Map(identity, orig)
+ if (*reflect.StringHeader)(unsafe.Pointer(&orig)).Data !=
+ (*reflect.StringHeader)(unsafe.Pointer(&m)).Data {
+ t.Error("unexpected copy during identity map")
+ }
}
func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
+func BenchmarkMapNoChanges(b *testing.B) {
+ identity := func(rune int) int {
+ return rune
+ }
+ for i := 0; i < b.N; i++ {
+ Map(identity, "Some string that won't be modified.")
+ }
+}
+
func TestSpecialCase(t *testing.T) {
lower := "abcçdefgğhıijklmnoöprsştuüvyz"
upper := "ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ"
@@ -617,7 +639,11 @@ func equal(m string, s1, s2 string, t *testing.T) bool {
func TestCaseConsistency(t *testing.T) {
// Make a string of all the runes.
- a := make([]int, unicode.MaxRune+1)
+ numRunes := unicode.MaxRune + 1
+ if testing.Short() {
+ numRunes = 1000
+ }
+ a := make([]int, numRunes)
for i := range a {
a[i] = i
}
@@ -627,10 +653,10 @@ func TestCaseConsistency(t *testing.T) {
lower := ToLower(s)
// Consistency checks
- if n := utf8.RuneCountInString(upper); n != unicode.MaxRune+1 {
+ if n := utf8.RuneCountInString(upper); n != numRunes {
t.Error("rune count wrong in upper:", n)
}
- if n := utf8.RuneCountInString(lower); n != unicode.MaxRune+1 {
+ if n := utf8.RuneCountInString(lower); n != numRunes {
t.Error("rune count wrong in lower:", n)
}
if !equal("ToUpper(upper)", ToUpper(upper), upper, t) {