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.
11 "golang.org/x/text/language"
14 // QueryIter represents a set of Units. The default set includes all Units that
15 // are currently in use as legal tender in any Region.
16 type QueryIter interface {
17 // Next returns true if there is a next element available.
18 // It must be called before any of the other methods are called.
21 // Unit returns the unit of the current iteration.
24 // Region returns the Region for the current iteration.
25 Region() language.Region
27 // From returns the date from which the unit was used in the region.
28 // It returns false if this date is unknown.
29 From() (time.Time, bool)
31 // To returns the date up till which the unit was used in the region.
32 // It returns false if this date is unknown or if the unit is still in use.
33 To() (time.Time, bool)
35 // IsTender reports whether the unit is a legal tender in the region during
36 // the specified date range.
40 // Query represents a set of Units. The default set includes all Units that are
41 // currently in use as legal tender in any Region.
42 func Query(options ...QueryOption) QueryIter {
47 for _, fn := range options {
53 // NonTender returns a new query that also includes matching Units that are not
55 var NonTender QueryOption = nonTender
57 func nonTender(i *iter) {
61 // Historical selects the units for all dates.
62 var Historical QueryOption = historical
64 func historical(i *iter) {
68 // A QueryOption can be used to change the set of unit information returned by
70 type QueryOption func(*iter)
72 // Date queries the units that were in use at the given point in history.
73 func Date(t time.Time) QueryOption {
75 return func(i *iter) {
80 // Region limits the query to only return entries for the given region.
81 func Region(r language.Region) QueryOption {
82 p, end := len(regionData), len(regionData)
84 i := sort.Search(len(regionData), func(i int) bool {
85 return regionData[i].region >= x
87 if i < len(regionData) && regionData[i].region == x {
89 for i++; i < len(regionData) && regionData[i].region == x; i++ {
93 return func(i *iter) {
110 func (i *iter) Next() bool {
111 for ; i.p < i.end; i.p++ {
112 i.regionInfo = ®ionData[i.p]
113 if !i.nonTender && !i.IsTender() {
116 if i.date == hist || (i.from <= i.date && (i.to == 0 || i.date <= i.to)) {
124 func (r *regionInfo) Region() language.Region {
125 // TODO: this could be much faster.
127 buf[0] = uint8(r.region >> 8)
128 buf[1] = uint8(r.region)
129 return language.MustParseRegion(string(buf[:]))
132 func (r *regionInfo) Unit() Unit {
133 return Unit{r.code &^ nonTenderBit}
136 func (r *regionInfo) IsTender() bool {
137 return r.code&nonTenderBit == 0
140 func (r *regionInfo) From() (time.Time, bool) {
142 return time.Time{}, false
144 return fromDate(r.from), true
147 func (r *regionInfo) To() (time.Time, bool) {
149 return time.Time{}, false
151 return fromDate(r.to), true