github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/text/internal/number/plural.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package number 6 7 import "github.com/insionng/yougam/libraries/x/text/internal/format/plural" 8 9 type pluralRules struct { 10 rules []pluralCheck 11 index []byte 12 langToIndex []byte 13 inclusionMasks []uint64 14 } 15 16 var ( 17 ordinalData = pluralRules{ 18 ordinalRules, 19 ordinalIndex, 20 ordinalLangToIndex, 21 ordinalInclusionMasks[:], 22 } 23 cardinalData = pluralRules{ 24 cardinalRules, 25 cardinalIndex, 26 cardinalLangToIndex, 27 cardinalInclusionMasks[:], 28 } 29 ) 30 31 // See gen_plural.go for an explanation of the algorithm. 32 33 func matchPlural(p *pluralRules, index int, n, f, v int) plural.Form { 34 nMask := p.inclusionMasks[n%maxMod] 35 // Compute the fMask inline in the rules below, as it is relatively rare. 36 // fMask := p.inclusionMasks[f%maxMod] 37 vMask := p.inclusionMasks[v%maxMod] 38 39 // Do the matching 40 offset := p.langToIndex[index] 41 rules := p.rules[p.index[offset]:p.index[offset+1]] 42 for i := 0; i < len(rules); i++ { 43 rule := rules[i] 44 setBit := uint64(1 << rule.setID) 45 var skip bool 46 switch op := opID(rule.cat >> opShift); op { 47 case opI: // i = x 48 skip = n >= numN || nMask&setBit == 0 49 50 case opI | opNotEqual: // i != x 51 skip = n < numN && nMask&setBit != 0 52 53 case opI | opMod: // i % m = x 54 skip = nMask&setBit == 0 55 56 case opI | opMod | opNotEqual: // i % m != x 57 skip = nMask&setBit != 0 58 59 case opN: // n = x 60 skip = f != 0 || n >= numN || nMask&setBit == 0 61 62 case opN | opNotEqual: // n != x 63 skip = f == 0 && n < numN && nMask&setBit != 0 64 65 case opN | opMod: // n % m = x 66 skip = f != 0 || nMask&setBit == 0 67 68 case opN | opMod | opNotEqual: // n % m != x 69 skip = f == 0 && nMask&setBit != 0 70 71 case opF: // f = x 72 skip = f >= numN || p.inclusionMasks[f%maxMod]&setBit == 0 73 74 case opF | opNotEqual: // f != x 75 skip = f < numN && p.inclusionMasks[f%maxMod]&setBit != 0 76 77 case opF | opMod: // f % m = x 78 skip = p.inclusionMasks[f%maxMod]&setBit == 0 79 80 case opF | opMod | opNotEqual: // f % m != x 81 skip = p.inclusionMasks[f%maxMod]&setBit != 0 82 83 case opV: // v = x 84 skip = v < numN && vMask&setBit == 0 85 86 case opV | opNotEqual: // v != x 87 skip = v < numN && vMask&setBit != 0 88 89 case opW: // w == 0 90 skip = f != 0 91 92 case opW | opNotEqual: // w != 0 93 skip = f == 0 94 95 // Hard-wired rules that cannot be handled by our algorithm. 96 97 case opBretonM: 98 skip = f != 0 || n == 0 || n%1000000 != 0 99 100 case opAzerbaijan00s: 101 // 100,200,300,400,500,600,700,800,900 102 skip = n == 0 || n >= 1000 || n%100 != 0 103 104 case opItalian800: 105 skip = (f != 0 || n >= numN || nMask&setBit == 0) && n != 800 106 } 107 if skip { 108 // advance over AND entries. 109 for ; i < len(rules) && rules[i].cat&formMask == andNext; i++ { 110 } 111 continue 112 } 113 // return if we have a final entry. 114 if cat := rule.cat & formMask; cat != andNext { 115 return plural.Form(cat) 116 } 117 } 118 return plural.Other 119 }