1 /*
2 *******************************************************************************
3 * Copyright (C) 2015, International Business Machines
4 * Corporation and others.  All Rights Reserved.
5 *******************************************************************************
6 * digitinterval.h
7 *
8 * created on: 2015jan6
9 * created by: Travis Keep
10 */
11 
12 #ifndef __DIGITINTERVAL_H__
13 #define __DIGITINTERVAL_H__
14 
15 #include "unicode/uobject.h"
16 #include "unicode/utypes.h"
17 
18 U_NAMESPACE_BEGIN
19 
20 /**
21  * An interval of digits.
22  * DigitIntervals are for fixed point formatting. A DigitInterval specifies
23  * zero or more integer digits and zero or more fractional digits. This class
24  * specifies particular digits in a number by their power of 10. For example,
25  * the digit position just to the left of the decimal is 0, and the digit
26  * position just left of that is 1. The digit position just to the right of
27  * the decimal is -1. The digit position just to the right of that is -2.
28  */
29 class U_I18N_API DigitInterval : public UMemory {
30 public:
31 
32     /**
33      * Spans all integer and fraction digits
34      */
DigitInterval()35     DigitInterval()
36             : fLargestExclusive(INT32_MAX), fSmallestInclusive(INT32_MIN) { }
37 
38 
39     /**
40      * Makes this instance span all digits.
41      */
clear()42     void clear() {
43         fLargestExclusive = INT32_MAX;
44         fSmallestInclusive = INT32_MIN;
45     }
46 
47     /**
48      * Returns TRUE if this interval contains this digit position.
49      */
50     UBool contains(int32_t digitPosition) const;
51 
52     /**
53      * Returns true if this object is the same as rhs.
54      */
equals(const DigitInterval & rhs)55     UBool equals(const DigitInterval &rhs) const {
56         return ((fLargestExclusive == rhs.fLargestExclusive) &&
57                 (fSmallestInclusive == rhs.fSmallestInclusive));
58     }
59 
60     /**
61      * Expand this interval so that it contains all of rhs.
62      */
63     void expandToContain(const DigitInterval &rhs);
64 
65     /**
66      * Shrink this interval so that it contains no more than rhs.
67      */
68     void shrinkToFitWithin(const DigitInterval &rhs);
69 
70     /**
71      * Expand this interval as necessary to contain digit with given exponent
72      * After this method returns, this interval is guaranteed to contain
73      * digitExponent.
74      */
75     void expandToContainDigit(int32_t digitExponent);
76 
77     /**
78      * Changes the number of digits to the left of the decimal point that
79      * this interval spans. If count is negative, it means span all digits
80      * to the left of the decimal point.
81      */
82     void setIntDigitCount(int32_t count);
83 
84     /**
85      * Changes the number of digits to the right of the decimal point that
86      * this interval spans. If count is negative, it means span all digits
87      * to the right of the decimal point.
88      */
89     void setFracDigitCount(int32_t count);
90 
91     /**
92      * Sets the least significant inclusive value to smallest. If smallest >= 0
93      * then least significant inclusive value becomes 0.
94      */
setLeastSignificantInclusive(int32_t smallest)95     void setLeastSignificantInclusive(int32_t smallest) {
96         fSmallestInclusive = smallest < 0 ? smallest : 0;
97     }
98 
99     /**
100      * Sets the most significant exclusive value to largest.
101      * If largest <= 0 then most significant exclusive value becomes 0.
102      */
setMostSignificantExclusive(int32_t largest)103     void setMostSignificantExclusive(int32_t largest) {
104         fLargestExclusive = largest > 0 ? largest : 0;
105     }
106 
107     /**
108      * If returns 8, the most significant digit in interval is the 10^7 digit.
109      * Returns INT32_MAX if this interval spans all digits to left of
110      * decimal point.
111      */
getMostSignificantExclusive()112     int32_t getMostSignificantExclusive() const {
113         return fLargestExclusive;
114     }
115 
116     /**
117      * Returns number of digits to the left of the decimal that this
118      * interval includes. This is a synonym for getMostSignificantExclusive().
119      */
getIntDigitCount()120     int32_t getIntDigitCount() const {
121         return fLargestExclusive;
122     }
123 
124     /**
125      * Returns number of digits to the right of the decimal that this
126      * interval includes.
127      */
getFracDigitCount()128     int32_t getFracDigitCount() const {
129         return fSmallestInclusive == INT32_MIN ? INT32_MAX : -fSmallestInclusive;
130     }
131 
132     /**
133      * Returns the total number of digits that this interval spans.
134      * Caution: If this interval spans all digits to the left or right of
135      * decimal point instead of some fixed number, then what length()
136      * returns is undefined.
137      */
length()138     int32_t length() const {
139         return fLargestExclusive - fSmallestInclusive;
140      }
141 
142     /**
143      * If returns -3, the least significant digit in interval is the 10^-3
144      * digit. Returns INT32_MIN if this interval spans all digits to right of
145      * decimal point.
146      */
getLeastSignificantInclusive()147     int32_t getLeastSignificantInclusive() const {
148         return fSmallestInclusive;
149     }
150 private:
151     int32_t fLargestExclusive;
152     int32_t fSmallestInclusive;
153 };
154 
155 U_NAMESPACE_END
156 
157 #endif  // __DIGITINTERVAL_H__
158