aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/text/internal/colltab/numeric.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/internal/colltab/numeric.go')
-rw-r--r--vendor/golang.org/x/text/internal/colltab/numeric.go236
1 files changed, 0 insertions, 236 deletions
diff --git a/vendor/golang.org/x/text/internal/colltab/numeric.go b/vendor/golang.org/x/text/internal/colltab/numeric.go
deleted file mode 100644
index 38c255c..0000000
--- a/vendor/golang.org/x/text/internal/colltab/numeric.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2014 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 colltab
-
-import (
- "unicode"
- "unicode/utf8"
-)
-
-// NewNumericWeighter wraps w to replace individual digits to sort based on their
-// numeric value.
-//
-// Weighter w must have a free primary weight after the primary weight for 9.
-// If this is not the case, numeric value will sort at the same primary level
-// as the first primary sorting after 9.
-func NewNumericWeighter(w Weighter) Weighter {
- getElem := func(s string) Elem {
- elems, _ := w.AppendNextString(nil, s)
- return elems[0]
- }
- nine := getElem("9")
-
- // Numbers should order before zero, but the DUCET has no room for this.
- // TODO: move before zero once we use fractional collation elements.
- ns, _ := MakeElem(nine.Primary()+1, nine.Secondary(), int(nine.Tertiary()), 0)
-
- return &numericWeighter{
- Weighter: w,
-
- // We assume that w sorts digits of different kinds in order of numeric
- // value and that the tertiary weight order is preserved.
- //
- // TODO: evaluate whether it is worth basing the ranges on the Elem
- // encoding itself once the move to fractional weights is complete.
- zero: getElem("0"),
- zeroSpecialLo: getElem("0"), // U+FF10 FULLWIDTH DIGIT ZERO
- zeroSpecialHi: getElem("₀"), // U+2080 SUBSCRIPT ZERO
- nine: nine,
- nineSpecialHi: getElem("₉"), // U+2089 SUBSCRIPT NINE
- numberStart: ns,
- }
-}
-
-// A numericWeighter translates a stream of digits into a stream of weights
-// representing the numeric value.
-type numericWeighter struct {
- Weighter
-
- // The Elems below all demarcate boundaries of specific ranges. With the
- // current element encoding digits are in two ranges: normal (default
- // tertiary value) and special. For most languages, digits have collation
- // elements in the normal range.
- //
- // Note: the range tests are very specific for the element encoding used by
- // this implementation. The tests in collate_test.go are designed to fail
- // if this code is not updated when an encoding has changed.
-
- zero Elem // normal digit zero
- zeroSpecialLo Elem // special digit zero, low tertiary value
- zeroSpecialHi Elem // special digit zero, high tertiary value
- nine Elem // normal digit nine
- nineSpecialHi Elem // special digit nine
- numberStart Elem
-}
-
-// AppendNext calls the namesake of the underlying weigher, but replaces single
-// digits with weights representing their value.
-func (nw *numericWeighter) AppendNext(buf []Elem, s []byte) (ce []Elem, n int) {
- ce, n = nw.Weighter.AppendNext(buf, s)
- nc := numberConverter{
- elems: buf,
- w: nw,
- b: s,
- }
- isZero, ok := nc.checkNextDigit(ce)
- if !ok {
- return ce, n
- }
- // ce might have been grown already, so take it instead of buf.
- nc.init(ce, len(buf), isZero)
- for n < len(s) {
- ce, sz := nw.Weighter.AppendNext(nc.elems, s[n:])
- nc.b = s
- n += sz
- if !nc.update(ce) {
- break
- }
- }
- return nc.result(), n
-}
-
-// AppendNextString calls the namesake of the underlying weigher, but replaces
-// single digits with weights representing their value.
-func (nw *numericWeighter) AppendNextString(buf []Elem, s string) (ce []Elem, n int) {
- ce, n = nw.Weighter.AppendNextString(buf, s)
- nc := numberConverter{
- elems: buf,
- w: nw,
- s: s,
- }
- isZero, ok := nc.checkNextDigit(ce)
- if !ok {
- return ce, n
- }
- nc.init(ce, len(buf), isZero)
- for n < len(s) {
- ce, sz := nw.Weighter.AppendNextString(nc.elems, s[n:])
- nc.s = s
- n += sz
- if !nc.update(ce) {
- break
- }
- }
- return nc.result(), n
-}
-
-type numberConverter struct {
- w *numericWeighter
-
- elems []Elem
- nDigits int
- lenIndex int
-
- s string // set if the input was of type string
- b []byte // set if the input was of type []byte
-}
-
-// init completes initialization of a numberConverter and prepares it for adding
-// more digits. elems is assumed to have a digit starting at oldLen.
-func (nc *numberConverter) init(elems []Elem, oldLen int, isZero bool) {
- // Insert a marker indicating the start of a number and and a placeholder
- // for the number of digits.
- if isZero {
- elems = append(elems[:oldLen], nc.w.numberStart, 0)
- } else {
- elems = append(elems, 0, 0)
- copy(elems[oldLen+2:], elems[oldLen:])
- elems[oldLen] = nc.w.numberStart
- elems[oldLen+1] = 0
-
- nc.nDigits = 1
- }
- nc.elems = elems
- nc.lenIndex = oldLen + 1
-}
-
-// checkNextDigit reports whether bufNew adds a single digit relative to the old
-// buffer. If it does, it also reports whether this digit is zero.
-func (nc *numberConverter) checkNextDigit(bufNew []Elem) (isZero, ok bool) {
- if len(nc.elems) >= len(bufNew) {
- return false, false
- }
- e := bufNew[len(nc.elems)]
- if e < nc.w.zeroSpecialLo || nc.w.nine < e {
- // Not a number.
- return false, false
- }
- if e < nc.w.zero {
- if e > nc.w.nineSpecialHi {
- // Not a number.
- return false, false
- }
- if !nc.isDigit() {
- return false, false
- }
- isZero = e <= nc.w.zeroSpecialHi
- } else {
- // This is the common case if we encounter a digit.
- isZero = e == nc.w.zero
- }
- // Test the remaining added collation elements have a zero primary value.
- if n := len(bufNew) - len(nc.elems); n > 1 {
- for i := len(nc.elems) + 1; i < len(bufNew); i++ {
- if bufNew[i].Primary() != 0 {
- return false, false
- }
- }
- // In some rare cases, collation elements will encode runes in
- // unicode.No as a digit. For example Ethiopic digits (U+1369 - U+1371)
- // are not in Nd. Also some digits that clearly belong in unicode.No,
- // like U+0C78 TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR, have
- // collation elements indistinguishable from normal digits.
- // Unfortunately, this means we need to make this check for nearly all
- // non-Latin digits.
- //
- // TODO: check the performance impact and find something better if it is
- // an issue.
- if !nc.isDigit() {
- return false, false
- }
- }
- return isZero, true
-}
-
-func (nc *numberConverter) isDigit() bool {
- if nc.b != nil {
- r, _ := utf8.DecodeRune(nc.b)
- return unicode.In(r, unicode.Nd)
- }
- r, _ := utf8.DecodeRuneInString(nc.s)
- return unicode.In(r, unicode.Nd)
-}
-
-// We currently support a maximum of about 2M digits (the number of primary
-// values). Such numbers will compare correctly against small numbers, but their
-// comparison against other large numbers is undefined.
-//
-// TODO: define a proper fallback, such as comparing large numbers textually or
-// actually allowing numbers of unlimited length.
-//
-// TODO: cap this to a lower number (like 100) and maybe allow a larger number
-// in an option?
-const maxDigits = 1<<maxPrimaryBits - 1
-
-func (nc *numberConverter) update(elems []Elem) bool {
- isZero, ok := nc.checkNextDigit(elems)
- if nc.nDigits == 0 && isZero {
- return true
- }
- nc.elems = elems
- if !ok {
- return false
- }
- nc.nDigits++
- return nc.nDigits < maxDigits
-}
-
-// result fills in the length element for the digit sequence and returns the
-// completed collation elements.
-func (nc *numberConverter) result() []Elem {
- e, _ := MakeElem(nc.nDigits, defaultSecondary, defaultTertiary, 0)
- nc.elems[nc.lenIndex] = e
- return nc.elems
-}