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