1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2017 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4package android.icu.number;
5
6import java.math.BigInteger;
7import java.util.concurrent.atomic.AtomicLongFieldUpdater;
8
9import android.icu.impl.Utility;
10import android.icu.impl.number.DecimalQuantity;
11import android.icu.impl.number.DecimalQuantity_DualStorageBCD;
12import android.icu.impl.number.MacroProps;
13import android.icu.impl.number.MicroProps;
14import android.icu.impl.number.NumberStringBuilder;
15import android.icu.math.BigDecimal;
16import android.icu.util.CurrencyAmount;
17import android.icu.util.Measure;
18import android.icu.util.MeasureUnit;
19
20/**
21 * A NumberFormatter that has a locale associated with it; this means .format() methods are available.
22 *
23 * @see NumberFormatter
24 * @see NumberFormatter
25 * @hide Only a subset of ICU is exposed in Android
26 * @hide draft / provisional / internal are hidden on Android
27 */
28public class LocalizedNumberFormatter extends NumberFormatterSettings<LocalizedNumberFormatter> {
29
30    static final AtomicLongFieldUpdater<LocalizedNumberFormatter> callCount = AtomicLongFieldUpdater
31            .newUpdater(LocalizedNumberFormatter.class, "callCountInternal");
32
33    volatile long callCountInternal; // do not access directly; use callCount instead
34    volatile LocalizedNumberFormatter savedWithUnit;
35    volatile NumberFormatterImpl compiled;
36
37    LocalizedNumberFormatter(NumberFormatterSettings<?> parent, int key, Object value) {
38        super(parent, key, value);
39    }
40
41    /**
42     * Format the given byte, short, int, or long to a string using the settings specified in the NumberFormatter fluent
43     * setting chain.
44     *
45     * @param input
46     *            The number to format.
47     * @return A FormattedNumber object; call .toString() to get the string.
48     * @see NumberFormatter
49     * @hide draft / provisional / internal are hidden on Android
50     */
51    public FormattedNumber format(long input) {
52        return format(new DecimalQuantity_DualStorageBCD(input));
53    }
54
55    /**
56     * Format the given float or double to a string using the settings specified in the NumberFormatter fluent setting
57     * chain.
58     *
59     * @param input
60     *            The number to format.
61     * @return A FormattedNumber object; call .toString() to get the string.
62     * @see NumberFormatter
63     * @hide draft / provisional / internal are hidden on Android
64     */
65    public FormattedNumber format(double input) {
66        return format(new DecimalQuantity_DualStorageBCD(input));
67    }
68
69    /**
70     * Format the given {@link BigInteger}, {@link BigDecimal}, or other {@link Number} to a string using the settings
71     * specified in the NumberFormatter fluent setting chain.
72     *
73     * @param input
74     *            The number to format.
75     * @return A FormattedNumber object; call .toString() to get the string.
76     * @see NumberFormatter
77     * @hide draft / provisional / internal are hidden on Android
78     */
79    public FormattedNumber format(Number input) {
80        return format(new DecimalQuantity_DualStorageBCD(input));
81    }
82
83    /**
84     * Format the given {@link Measure} or {@link CurrencyAmount} to a string using the settings specified in the
85     * NumberFormatter fluent setting chain.
86     *
87     * <p>
88     * The unit specified here overrides any unit that may have been specified in the setter chain. This method is
89     * intended for cases when each input to the number formatter has a different unit.
90     *
91     * @param input
92     *            The number to format.
93     * @return A FormattedNumber object; call .toString() to get the string.
94     * @see NumberFormatter
95     * @hide draft / provisional / internal are hidden on Android
96     */
97    public FormattedNumber format(Measure input) {
98        MeasureUnit unit = input.getUnit();
99        Number number = input.getNumber();
100        // Use this formatter if possible
101        if (Utility.equals(resolve().unit, unit)) {
102            return format(number);
103        }
104        // This mechanism saves the previously used unit, so if the user calls this method with the
105        // same unit multiple times in a row, they get a more efficient code path.
106        LocalizedNumberFormatter withUnit = savedWithUnit;
107        if (withUnit == null || !Utility.equals(withUnit.resolve().unit, unit)) {
108            withUnit = new LocalizedNumberFormatter(this, KEY_UNIT, unit);
109            savedWithUnit = withUnit;
110        }
111        return withUnit.format(number);
112    }
113
114    /**
115     * This is the core entrypoint to the number formatting pipeline. It performs self-regulation: a static code path
116     * for the first few calls, and compiling a more efficient data structure if called repeatedly.
117     *
118     * <p>
119     * This function is very hot, being called in every call to the number formatting pipeline.
120     *
121     * @param fq
122     *            The quantity to be formatted.
123     * @return The formatted number result.
124     *
125     * @deprecated ICU 60 This API is ICU internal only.
126     * @hide draft / provisional / internal are hidden on Android
127     */
128    @Deprecated
129    public FormattedNumber format(DecimalQuantity fq) {
130        MacroProps macros = resolve();
131        // NOTE: In Java, the atomic increment logic is slightly different than ICU4C.
132        // It seems to be more efficient to make just one function call instead of two.
133        // Further benchmarking is required.
134        long currentCount = callCount.incrementAndGet(this);
135        NumberStringBuilder string = new NumberStringBuilder();
136        MicroProps micros;
137        if (currentCount == macros.threshold.longValue()) {
138            compiled = NumberFormatterImpl.fromMacros(macros);
139            micros = compiled.apply(fq, string);
140        } else if (compiled != null) {
141            micros = compiled.apply(fq, string);
142        } else {
143            micros = NumberFormatterImpl.applyStatic(macros, fq, string);
144        }
145        return new FormattedNumber(string, fq, micros);
146    }
147
148    @Override
149    LocalizedNumberFormatter create(int key, Object value) {
150        return new LocalizedNumberFormatter(this, key, value);
151    }
152}