2017-09-27 00:25:20 +00:00
|
|
|
// © 2017 and later: Unicode, Inc. and others.
|
|
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
|
|
|
2017-10-04 22:51:06 +00:00
|
|
|
#include "unicode/utypes.h"
|
|
|
|
|
2017-10-05 00:47:38 +00:00
|
|
|
#if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT
|
2017-09-27 05:31:57 +00:00
|
|
|
#ifndef __NUMBER_PATTERNMODIFIER_H__
|
|
|
|
#define __NUMBER_PATTERNMODIFIER_H__
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-09-27 05:31:57 +00:00
|
|
|
#include "standardplural.h"
|
2017-09-27 00:25:20 +00:00
|
|
|
#include "unicode/numberformatter.h"
|
|
|
|
#include "number_patternstring.h"
|
|
|
|
#include "number_types.h"
|
|
|
|
#include "number_modifiers.h"
|
|
|
|
#include "number_utils.h"
|
|
|
|
|
|
|
|
U_NAMESPACE_BEGIN
|
|
|
|
namespace number {
|
|
|
|
namespace impl {
|
|
|
|
|
2017-09-28 22:53:31 +00:00
|
|
|
// Forward declaration
|
|
|
|
class MutablePatternModifier;
|
2017-10-04 03:13:36 +00:00
|
|
|
|
|
|
|
// Export an explicit template instantiation of the LocalPointer that is used as a
|
|
|
|
// data member of ParameterizedModifier.
|
|
|
|
// (MSVC requires this, even though it should not be necessary.)
|
|
|
|
#if defined (_MSC_VER)
|
|
|
|
// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
|
|
|
|
#pragma warning(suppress: 4661)
|
|
|
|
template class U_I18N_API LocalPointerBase<ParameterizedModifier>;
|
|
|
|
template class U_I18N_API LocalPointer<ParameterizedModifier>;
|
|
|
|
#endif
|
|
|
|
|
2017-09-28 22:53:31 +00:00
|
|
|
// Exported as U_I18N_API because it is needed for the unit test PatternModifierTest
|
2017-10-06 02:03:16 +00:00
|
|
|
class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public UMemory {
|
2017-09-27 00:25:20 +00:00
|
|
|
public:
|
2017-10-04 01:23:58 +00:00
|
|
|
~ImmutablePatternModifier() U_OVERRIDE = default;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
void processQuantity(DecimalQuantity &, MicroProps µs, UErrorCode &status) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
|
|
|
void applyToMicros(MicroProps µs, DecimalQuantity &quantity) const;
|
|
|
|
|
|
|
|
private:
|
2017-10-02 22:55:16 +00:00
|
|
|
ImmutablePatternModifier(ParameterizedModifier *pm, const PluralRules *rules, const MicroPropsGenerator *parent);
|
2017-09-28 22:53:31 +00:00
|
|
|
|
2017-10-02 22:55:16 +00:00
|
|
|
const LocalPointer<ParameterizedModifier> pm;
|
2017-09-27 00:25:20 +00:00
|
|
|
const PluralRules *rules;
|
|
|
|
const MicroPropsGenerator *parent;
|
2017-09-28 22:53:31 +00:00
|
|
|
|
|
|
|
friend class MutablePatternModifier;
|
2017-09-27 00:25:20 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in
|
|
|
|
* {@link Modifier#apply}.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* In addition to being a Modifier, this class contains the business logic for substituting the correct locale symbols
|
|
|
|
* into the affixes of the decimal format pattern.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* In order to use this class, create a new instance and call the following four setters: {@link #setPatternInfo},
|
|
|
|
* {@link #setPatternAttributes}, {@link #setSymbols}, and {@link #setNumberProperties}. After calling these four
|
|
|
|
* setters, the instance will be ready for use as a Modifier.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* This is a MUTABLE, NON-THREAD-SAFE class designed for performance. Do NOT save references to this or attempt to use
|
|
|
|
* it from multiple threads! Instead, you can obtain a safe, immutable decimal format pattern modifier by calling
|
|
|
|
* {@link MutablePatternModifier#createImmutable}, in effect treating this instance as a builder for the immutable
|
|
|
|
* variant.
|
|
|
|
*/
|
2017-09-27 18:50:44 +00:00
|
|
|
class U_I18N_API MutablePatternModifier
|
2017-10-06 02:03:16 +00:00
|
|
|
: public MicroPropsGenerator,
|
|
|
|
public Modifier,
|
|
|
|
public SymbolProvider,
|
|
|
|
public CharSequence,
|
|
|
|
public UMemory {
|
2017-09-27 00:25:20 +00:00
|
|
|
public:
|
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
~MutablePatternModifier() U_OVERRIDE = default;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param isStrong
|
|
|
|
* Whether the modifier should be considered strong. For more information, see
|
|
|
|
* {@link Modifier#isStrong()}. Most of the time, decimal format pattern modifiers should be considered
|
|
|
|
* as non-strong.
|
|
|
|
*/
|
|
|
|
explicit MutablePatternModifier(bool isStrong);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets a reference to the parsed decimal format pattern, usually obtained from
|
|
|
|
* {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of {@link AffixPatternProvider} is
|
|
|
|
* accepted.
|
|
|
|
*/
|
|
|
|
void setPatternInfo(const AffixPatternProvider *patternInfo);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets attributes that imply changes to the literal interpretation of the pattern string affixes.
|
|
|
|
*
|
|
|
|
* @param signDisplay
|
|
|
|
* Whether to force a plus sign on positive numbers.
|
|
|
|
* @param perMille
|
|
|
|
* Whether to substitute the percent sign in the pattern with a permille sign.
|
|
|
|
*/
|
|
|
|
void setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets locale-specific details that affect the symbols substituted into the pattern string affixes.
|
|
|
|
*
|
|
|
|
* @param symbols
|
|
|
|
* The desired instance of DecimalFormatSymbols.
|
|
|
|
* @param currency
|
|
|
|
* The currency to be used when substituting currency values into the affixes.
|
|
|
|
* @param unitWidth
|
|
|
|
* The width used to render currencies.
|
|
|
|
* @param rules
|
|
|
|
* Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the
|
|
|
|
* convenience method {@link #needsPlurals()}.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
setSymbols(const DecimalFormatSymbols *symbols, const CurrencyUnit ¤cy, UNumberUnitWidth unitWidth,
|
|
|
|
const PluralRules *rules);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets attributes of the current number being processed.
|
|
|
|
*
|
|
|
|
* @param isNegative
|
|
|
|
* Whether the number is negative.
|
|
|
|
* @param plural
|
|
|
|
* The plural form of the number, required only if the pattern contains the triple currency sign, "¤¤¤"
|
|
|
|
* (and as indicated by {@link #needsPlurals()}).
|
|
|
|
*/
|
|
|
|
void setNumberProperties(bool isNegative, StandardPlural::Form plural);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize.
|
|
|
|
* This is currently true only if there is a currency long name placeholder in the pattern ("¤¤¤").
|
|
|
|
*/
|
|
|
|
bool needsPlurals() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable
|
|
|
|
* and can be saved for future use. The number properties in the current instance are mutated; all other properties
|
|
|
|
* are left untouched.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* The resulting modifier cannot be used in a QuantityChain.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
|
|
|
|
*
|
|
|
|
* @return An immutable that supports both positive and negative numbers.
|
|
|
|
*/
|
|
|
|
ImmutablePatternModifier *createImmutable(UErrorCode &status);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable
|
|
|
|
* and can be saved for future use. The number properties in the current instance are mutated; all other properties
|
|
|
|
* are left untouched.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
|
|
|
|
*
|
|
|
|
* @param parent
|
|
|
|
* The QuantityChain to which to chain this immutable.
|
|
|
|
* @return An immutable that supports both positive and negative numbers.
|
|
|
|
*/
|
|
|
|
ImmutablePatternModifier *
|
|
|
|
createImmutableAndChain(const MicroPropsGenerator *parent, UErrorCode &status);
|
|
|
|
|
|
|
|
MicroPropsGenerator &addToChain(const MicroPropsGenerator *parent);
|
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
void processQuantity(DecimalQuantity &, MicroProps µs, UErrorCode &status) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
|
|
|
int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
|
2017-10-04 01:23:58 +00:00
|
|
|
UErrorCode &status) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
int32_t getPrefixLength(UErrorCode &status) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
int32_t getCodePointCount(UErrorCode &status) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
bool isStrong() const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the string that substitutes a given symbol type in a pattern.
|
|
|
|
*/
|
2017-10-04 01:23:58 +00:00
|
|
|
UnicodeString getSymbol(AffixPatternType type) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
int32_t length() const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
char16_t charAt(int32_t index) const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
|
|
|
// Use default implementation of codePointAt
|
|
|
|
|
2017-10-04 01:23:58 +00:00
|
|
|
UnicodeString toUnicodeString() const U_OVERRIDE;
|
2017-09-27 00:25:20 +00:00
|
|
|
|
|
|
|
private:
|
2017-10-04 22:29:21 +00:00
|
|
|
// Modifier details (initialized in constructor)
|
2017-09-27 00:25:20 +00:00
|
|
|
const bool fStrong;
|
|
|
|
|
2017-10-04 22:29:21 +00:00
|
|
|
// Pattern details (initialized in setPatternInfo and setPatternAttributes)
|
2017-09-27 00:25:20 +00:00
|
|
|
const AffixPatternProvider *patternInfo;
|
|
|
|
UNumberSignDisplay signDisplay;
|
|
|
|
bool perMilleReplacesPercent;
|
|
|
|
|
2017-10-04 22:29:21 +00:00
|
|
|
// Symbol details (initialized in setSymbols)
|
2017-09-27 00:25:20 +00:00
|
|
|
const DecimalFormatSymbols *symbols;
|
|
|
|
UNumberUnitWidth unitWidth;
|
|
|
|
char16_t currencyCode[4];
|
|
|
|
const PluralRules *rules;
|
|
|
|
|
2017-10-04 22:29:21 +00:00
|
|
|
// Number details (initialized in setNumberProperties)
|
2017-09-27 00:25:20 +00:00
|
|
|
bool isNegative;
|
|
|
|
StandardPlural::Form plural;
|
|
|
|
|
2017-10-04 22:29:21 +00:00
|
|
|
// QuantityChain details (initialized in addToChain)
|
2017-09-27 00:25:20 +00:00
|
|
|
const MicroPropsGenerator *parent;
|
|
|
|
|
2017-10-04 22:29:21 +00:00
|
|
|
// Transient CharSequence fields (initialized in enterCharSequenceMode)
|
2017-09-27 03:02:02 +00:00
|
|
|
bool inCharSequenceMode = false;
|
2017-09-27 00:25:20 +00:00
|
|
|
int32_t fFlags;
|
|
|
|
int32_t fLength;
|
|
|
|
bool prependSign;
|
|
|
|
bool plusReplacesMinusSign;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support
|
|
|
|
* if required.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
|
|
|
|
*
|
|
|
|
* @param a
|
|
|
|
* A working NumberStringBuilder object; passed from the outside to prevent the need to create many new
|
|
|
|
* instances if this method is called in a loop.
|
|
|
|
* @param b
|
|
|
|
* Another working NumberStringBuilder object.
|
|
|
|
* @return The constant modifier object.
|
|
|
|
*/
|
|
|
|
ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status);
|
|
|
|
|
|
|
|
int32_t insertPrefix(NumberStringBuilder &sb, int position, UErrorCode &status);
|
|
|
|
|
|
|
|
int32_t insertSuffix(NumberStringBuilder &sb, int position, UErrorCode &status);
|
|
|
|
|
|
|
|
void enterCharSequenceMode(bool isPrefix);
|
|
|
|
|
|
|
|
void exitCharSequenceMode();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace impl
|
|
|
|
} // namespace number
|
|
|
|
U_NAMESPACE_END
|
|
|
|
|
2017-09-27 05:31:57 +00:00
|
|
|
#endif //__NUMBER_PATTERNMODIFIER_H__
|
|
|
|
|
|
|
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|