220 lines
7.9 KiB
Java
220 lines
7.9 KiB
Java
/* GENERATED SOURCE. DO NOT MODIFY. */
|
|
// © 2018 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
package android.icu.number;
|
|
|
|
import android.icu.impl.number.range.RangeMacroProps;
|
|
import android.icu.number.NumberRangeFormatter.RangeCollapse;
|
|
import android.icu.number.NumberRangeFormatter.RangeIdentityFallback;
|
|
import android.icu.util.ULocale;
|
|
|
|
/**
|
|
* An abstract base class for specifying settings related to number formatting. This class is implemented by
|
|
* {@link UnlocalizedNumberRangeFormatter} and {@link LocalizedNumberRangeFormatter}. This class is not intended for
|
|
* public subclassing.
|
|
*
|
|
* @author sffc
|
|
* @see NumberRangeFormatter
|
|
*/
|
|
public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatterSettings<?>> {
|
|
|
|
static final int KEY_MACROS = 0; // not used
|
|
static final int KEY_LOCALE = 1;
|
|
static final int KEY_FORMATTER_1 = 2;
|
|
static final int KEY_FORMATTER_2 = 3;
|
|
static final int KEY_SAME_FORMATTERS = 4;
|
|
static final int KEY_COLLAPSE = 5;
|
|
static final int KEY_IDENTITY_FALLBACK = 6;
|
|
static final int KEY_MAX = 7;
|
|
|
|
private final NumberRangeFormatterSettings<?> parent;
|
|
private final int key;
|
|
private final Object value;
|
|
private volatile RangeMacroProps resolvedMacros;
|
|
|
|
NumberRangeFormatterSettings(NumberRangeFormatterSettings<?> parent, int key, Object value) {
|
|
this.parent = parent;
|
|
this.key = key;
|
|
this.value = value;
|
|
}
|
|
|
|
/**
|
|
* Sets the NumberFormatter instance to use for the numbers in the range. The same formatter is applied to both
|
|
* sides of the range.
|
|
* <p>
|
|
* The NumberFormatter instances must not have a locale applied yet; the locale specified on the
|
|
* NumberRangeFormatter will be used.
|
|
*
|
|
* @param formatter
|
|
* The formatter to use for both numbers in the range.
|
|
* @return The fluent chain.
|
|
* @see NumberFormatter
|
|
* @see NumberRangeFormatter
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public T numberFormatterBoth(UnlocalizedNumberFormatter formatter) {
|
|
return (T) create(KEY_SAME_FORMATTERS, true).create(KEY_FORMATTER_1, formatter);
|
|
}
|
|
|
|
/**
|
|
* Sets the NumberFormatter instance to use for the first number in the range.
|
|
* <p>
|
|
* The NumberFormatter instance must not have a locale applied yet; the locale specified on the
|
|
* NumberRangeFormatter will be used.
|
|
*
|
|
* @param formatterFirst
|
|
* The formatter to use for the first number in the range.
|
|
* @return The fluent chain.
|
|
* @see NumberFormatter
|
|
* @see NumberRangeFormatter
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public T numberFormatterFirst(UnlocalizedNumberFormatter formatterFirst) {
|
|
return (T) create(KEY_SAME_FORMATTERS, false).create(KEY_FORMATTER_1, formatterFirst);
|
|
}
|
|
|
|
/**
|
|
* Sets the NumberFormatter instances to use for the second number in the range.
|
|
* <p>
|
|
* The NumberFormatter instance must not have a locale applied yet; the locale specified on the
|
|
* NumberRangeFormatter will be used.
|
|
*
|
|
* @param formatterSecond
|
|
* The formatter to use for the second number in the range.
|
|
* @return The fluent chain.
|
|
* @see NumberFormatter
|
|
* @see NumberRangeFormatter
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public T numberFormatterSecond(UnlocalizedNumberFormatter formatterSecond) {
|
|
return (T) create(KEY_SAME_FORMATTERS, false).create(KEY_FORMATTER_2, formatterSecond);
|
|
}
|
|
|
|
/**
|
|
* Sets the aggressiveness of "collapsing" fields across the range separator. Possible values:
|
|
* <ul>
|
|
* <li>ALL: "3-5K miles"</li>
|
|
* <li>UNIT: "3K - 5K miles"</li>
|
|
* <li>NONE: "3K miles - 5K miles"</li>
|
|
* <li>AUTO: usually UNIT or NONE, depending on the locale and formatter settings</li>
|
|
* </ul>
|
|
* <p>
|
|
* The default value is AUTO.
|
|
*
|
|
* @param collapse
|
|
* The collapsing strategy to use for this range.
|
|
* @return The fluent chain.
|
|
* @see NumberRangeFormatter
|
|
*/
|
|
public T collapse(RangeCollapse collapse) {
|
|
return create(KEY_COLLAPSE, collapse);
|
|
}
|
|
|
|
/**
|
|
* Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are
|
|
* passed to the formatRange function, or if different numbers are passed to the function but they become the same
|
|
* after rounding rules are applied. Possible values:
|
|
* <ul>
|
|
* <li>SINGLE_VALUE: "5 miles"</li>
|
|
* <li>APPROXIMATELY_OR_SINGLE_VALUE: "~5 miles" or "5 miles", depending on whether the number was the same before
|
|
* rounding was applied</li>
|
|
* <li>APPROXIMATELY: "~5 miles"</li>
|
|
* <li>RANGE: "5-5 miles" (with collapse=UNIT)</li>
|
|
* </ul>
|
|
* <p>
|
|
* The default value is APPROXIMATELY.
|
|
*
|
|
* @param identityFallback
|
|
* The strategy to use when formatting two numbers that end up being the same.
|
|
* @return The fluent chain.
|
|
* @see NumberRangeFormatter
|
|
*/
|
|
public T identityFallback(RangeIdentityFallback identityFallback) {
|
|
return create(KEY_IDENTITY_FALLBACK, identityFallback);
|
|
}
|
|
|
|
/* package-protected */ abstract T create(int key, Object value);
|
|
|
|
RangeMacroProps resolve() {
|
|
if (resolvedMacros != null) {
|
|
return resolvedMacros;
|
|
}
|
|
// Although the linked-list fluent storage approach requires this method,
|
|
// my benchmarks show that linked-list is still faster than a full clone
|
|
// of a MacroProps object at each step.
|
|
// TODO: Remove the reference to the parent after the macros are resolved?
|
|
RangeMacroProps macros = new RangeMacroProps();
|
|
// Bitmap: 1 if seen; 0 if unseen
|
|
long seen = 0;
|
|
NumberRangeFormatterSettings<?> current = this;
|
|
while (current != null) {
|
|
long keyBitmask = (1L << current.key);
|
|
if (0 != (seen & keyBitmask)) {
|
|
current = current.parent;
|
|
continue;
|
|
}
|
|
seen |= keyBitmask;
|
|
switch (current.key) {
|
|
case KEY_MACROS:
|
|
// ignored for now
|
|
break;
|
|
case KEY_LOCALE:
|
|
macros.loc = (ULocale) current.value;
|
|
break;
|
|
case KEY_FORMATTER_1:
|
|
macros.formatter1 = (UnlocalizedNumberFormatter) current.value;
|
|
break;
|
|
case KEY_FORMATTER_2:
|
|
macros.formatter2 = (UnlocalizedNumberFormatter) current.value;
|
|
break;
|
|
case KEY_SAME_FORMATTERS:
|
|
macros.sameFormatters = (boolean) current.value ? 1 : 0;
|
|
break;
|
|
case KEY_COLLAPSE:
|
|
macros.collapse = (RangeCollapse) current.value;
|
|
break;
|
|
case KEY_IDENTITY_FALLBACK:
|
|
macros.identityFallback = (RangeIdentityFallback) current.value;
|
|
break;
|
|
default:
|
|
throw new AssertionError("Unknown key: " + current.key);
|
|
}
|
|
current = current.parent;
|
|
}
|
|
// Copy the locale into the children (see touchRangeLocales in C++)
|
|
if (macros.formatter1 != null) {
|
|
macros.formatter1.resolve().loc = macros.loc;
|
|
}
|
|
if (macros.formatter2 != null) {
|
|
macros.formatter2.resolve().loc = macros.loc;
|
|
}
|
|
resolvedMacros = macros;
|
|
return macros;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public int hashCode() {
|
|
return resolve().hashCode();
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public boolean equals(Object other) {
|
|
if (this == other) {
|
|
return true;
|
|
}
|
|
if (other == null) {
|
|
return false;
|
|
}
|
|
if (!(other instanceof NumberRangeFormatterSettings)) {
|
|
return false;
|
|
}
|
|
return resolve().equals(((NumberRangeFormatterSettings<?>) other).resolve());
|
|
}
|
|
}
|