aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/text/internal/stringset
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/internal/stringset')
-rw-r--r--vendor/golang.org/x/text/internal/stringset/set.go86
-rw-r--r--vendor/golang.org/x/text/internal/stringset/set_test.go53
2 files changed, 139 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/internal/stringset/set.go b/vendor/golang.org/x/text/internal/stringset/set.go
new file mode 100644
index 0000000..bb2fffb
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/stringset/set.go
@@ -0,0 +1,86 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package stringset provides a way to represent a collection of strings
+// compactly.
+package stringset
+
+import "sort"
+
+// A Set holds a collection of strings that can be looked up by an index number.
+type Set struct {
+ // These fields are exported to allow for code generation.
+
+ Data string
+ Index []uint16
+}
+
+// Elem returns the string with index i. It panics if i is out of range.
+func (s *Set) Elem(i int) string {
+ return s.Data[s.Index[i]:s.Index[i+1]]
+}
+
+// Len returns the number of strings in the set.
+func (s *Set) Len() int {
+ return len(s.Index) - 1
+}
+
+// Search returns the index of the given string or -1 if it is not in the set.
+// The Set must have been created with strings in sorted order.
+func Search(s *Set, str string) int {
+ // TODO: optimize this if it gets used a lot.
+ n := len(s.Index) - 1
+ p := sort.Search(n, func(i int) bool {
+ return s.Elem(i) >= str
+ })
+ if p == n || str != s.Elem(p) {
+ return -1
+ }
+ return p
+}
+
+// A Builder constructs Sets.
+type Builder struct {
+ set Set
+ index map[string]int
+}
+
+// NewBuilder returns a new and initialized Builder.
+func NewBuilder() *Builder {
+ return &Builder{
+ set: Set{
+ Index: []uint16{0},
+ },
+ index: map[string]int{},
+ }
+}
+
+// Set creates the set created so far.
+func (b *Builder) Set() Set {
+ return b.set
+}
+
+// Index returns the index for the given string, which must have been added
+// before.
+func (b *Builder) Index(s string) int {
+ return b.index[s]
+}
+
+// Add adds a string to the index. Strings that are added by a single Add will
+// be stored together, unless they match an existing string.
+func (b *Builder) Add(ss ...string) {
+ // First check if the string already exists.
+ for _, s := range ss {
+ if _, ok := b.index[s]; ok {
+ continue
+ }
+ b.index[s] = len(b.set.Index) - 1
+ b.set.Data += s
+ x := len(b.set.Data)
+ if x > 0xFFFF {
+ panic("Index too > 0xFFFF")
+ }
+ b.set.Index = append(b.set.Index, uint16(x))
+ }
+}
diff --git a/vendor/golang.org/x/text/internal/stringset/set_test.go b/vendor/golang.org/x/text/internal/stringset/set_test.go
new file mode 100644
index 0000000..97b9e58
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/stringset/set_test.go
@@ -0,0 +1,53 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package stringset
+
+import "testing"
+
+func TestStringSet(t *testing.T) {
+ testCases := [][]string{
+ {""},
+ {"∫"},
+ {"a", "b", "c"},
+ {"", "a", "bb", "ccc"},
+ {" ", "aaa", "bb", "c"},
+ }
+ test := func(tc int, b *Builder) {
+ set := b.Set()
+ if set.Len() != len(testCases[tc]) {
+ t.Errorf("%d:Len() = %d; want %d", tc, set.Len(), len(testCases[tc]))
+ }
+ for i, s := range testCases[tc] {
+ if x := b.Index(s); x != i {
+ t.Errorf("%d:Index(%q) = %d; want %d", tc, s, x, i)
+ }
+ if p := Search(&set, s); p != i {
+ t.Errorf("%d:Search(%q) = %d; want %d", tc, s, p, i)
+ }
+ if set.Elem(i) != s {
+ t.Errorf("%d:Elem(%d) = %s; want %s", tc, i, set.Elem(i), s)
+ }
+ }
+ if p := Search(&set, "apple"); p != -1 {
+ t.Errorf(`%d:Search("apple") = %d; want -1`, tc, p)
+ }
+ }
+ for i, tc := range testCases {
+ b := NewBuilder()
+ for _, s := range tc {
+ b.Add(s)
+ }
+ b.Add(tc...)
+ test(i, b)
+ }
+ for i, tc := range testCases {
+ b := NewBuilder()
+ b.Add(tc...)
+ for _, s := range tc {
+ b.Add(s)
+ }
+ test(i, b)
+ }
+}