/*
********************************************************************************
*   Copyright (C) 1997-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
********************************************************************************
*
* File DCFMTSYM.H
*
* Modification History:
* 
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   03/18/97    clhuang     Updated per C++ implementation.
*   03/27/97    helena      Updated to pass the simple test after code review.
*   08/26/97    aliu        Added currency/intl currency symbol support.
*   07/22/98    stephen     Changed to match C++ style 
*                            currencySymbol -> fCurrencySymbol
*                            Constants changed from CAPS to kCaps
*   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
*   09/22/00    grhoten     Marked deprecation tags with a pointer to replacement
*                            functions.
********************************************************************************
*/
 
#ifndef DCFMTSYM_H
#define DCFMTSYM_H
 
#include "unicode/utypes.h"
#include "unicode/locid.h"

/**
 * This class represents the set of symbols needed by DecimalFormat
 * to format numbers. DecimalFormat creates for itself an instance of
 * DecimalFormatSymbols from its locale data.  If you need to change any
 * of these symbols, you can get the DecimalFormatSymbols object from
 * your DecimalFormat and modify it.
 * <P>
 * Here are the special characters used in the parts of the
 * subpattern, with notes on their usage.
 * <pre>
 * .       Symbol   Meaning
 * .         0      a digit
 * .         #      a digit, zero shows as absent
 * .         .      placeholder for decimal separator
 * .         ,      placeholder for grouping separator.
 * .         ;      separates formats.
 * .         -      default negative prefix.
 * .         %      divide by 100 and show as percentage
 * .         X      any other characters can be used in the prefix or suffix
 * .         '      used to quote special characters in a prefix or suffix.
 *  </pre>
 * [Notes]
 * <P>
 * If there is no explicit negative subpattern, - is prefixed to the
 * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00".
 * <P>
 * The grouping separator is commonly used for thousands, but in some
 * countries for ten-thousands. The interval is a constant number of
 * digits between the grouping characters, such as 100,000,000 or 1,0000,0000.
 * If you supply a pattern with multiple grouping characters, the interval
 * between the last one and the end of the integer is the one that is
 * used. So "#,##,###,####" == "######,####" == "##,####,####".
 * <P>
 * This class only handles localized digits where the 10 digits are
 * contiguous in Unicode, from 0 to 9. Other digits sets (such as
 * superscripts) would need a different subclass.
 * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
 */
class U_I18N_API DecimalFormatSymbols {
public:
    /**
     * Constants for specifying a number format symbol.
     * @draft
     */
    enum ENumberFormatSymbol {
        /** The decimal separator */
        kDecimalSeparatorSymbol,
        /** The grouping separator */
        kGroupingSeparatorSymbol,
        /** The pattern separator */
        kPatternSeparatorSymbol,
        /** The percent sign */
        kPercentSymbol,
        /** Zero*/
        kZeroDigitSymbol,
        /** Character representing a digit in the pattern */
        kDigitSymbol,
        /** The minus sign */
        kMinusSignSymbol,
        /** The plus sign */
        kPlusSignSymbol,
        /** The currency symbol */
        kCurrencySymbol,
        /** The international currency symbol */
        kIntlCurrencySymbol,
        /** The monetary separator */
        kMonetarySeparatorSymbol,
        /** The exponential symbol */
        kExponentialSymbol,
        /** Per mill symbol */
        kPermillSymbol,
        /** Escape padding character */
        kPadEscapeSymbol,
        /** Infinity symbol */
        kInfinitySymbol,
        /** Nan symbol */
        kNaNSymbol,
        /** count symbol constants */
        kFormatSymbolCount
    };

    /**
     * Create a DecimalFormatSymbols object for the given locale.
     *
     * @param locale    The locale to get symbols for.
     * @param status    Input/output parameter, set to success or
     *                  failure code upon return.
     * @stable
     */
    DecimalFormatSymbols(const Locale& locale, UErrorCode& status);

    /**
     * Create a DecimalFormatSymbols object for the default locale.
     * This constructor will not fail.  If the resource file data is
     * not available, it will use hard-coded last-resort data and
     * set status to U_USING_FALLBACK_ERROR.
     *
     * @param status    Input/output parameter, set to success or
     *                  failure code upon return.
     * @stable
     */
    DecimalFormatSymbols( UErrorCode& status);

    /**
     * Copy constructor.
     * @stable
     */
    DecimalFormatSymbols(const DecimalFormatSymbols&);

    /**
     * Assignment operator.
     * @stable
     */
    DecimalFormatSymbols& operator=(const DecimalFormatSymbols&);

    /**
     * Destructor.
     * @stable
     */
    ~DecimalFormatSymbols();

    /**
     * Return true if another object is semantically equal to this one.
     * @stable
     */
    UBool operator==(const DecimalFormatSymbols& other) const;

    /**
     * Return true if another object is semantically unequal to this one.
     * @stable
     */
    UBool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); }

    /**
     * Get one of the format symbols by its enum constant.
     * Each symbol is stored as a string so that graphemes
     * (characters with modifyer letters) can be used.
     * @draft
     */
    UnicodeString getSymbol(ENumberFormatSymbol symbol) const;

    /**
     * Set one of the format symbols by its enum constant.
     * Each symbol is stored as a string so that graphemes
     * (characters with modifyer letters) can be used.
     * @draft
     */
    void setSymbol(ENumberFormatSymbol symbol, UnicodeString value);

    /**
     * character used for zero. Different for Arabic, etc.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getZeroDigit(void) const;
    /**
     * character used for zero. Different for Arabic, etc.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setZeroDigit(UChar zeroDigit);

    /**
     * character used for thousands separator. Different for French, etc.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getGroupingSeparator(void) const;
    /**
     * character used for thousands separator. Different for French, etc.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setGroupingSeparator(UChar groupingSeparator);

    /**
     * character used for decimal sign. Different for French, etc.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getDecimalSeparator(void) const;
    /**
     * character used for decimal sign. Different for French, etc.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setDecimalSeparator(UChar decimalSeparator);

    /**
     * character used for per mill sign. Different for Arabic, etc.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getPerMill(void) const;
    /**
     * character used for per mill sign. Different for Arabic, etc.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setPerMill(UChar permill);

    /**
     * character used for percent sign. Different for Arabic, etc.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getPercent(void) const;
    /**
     * character used for percent sign. Different for Arabic, etc.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setPercent(UChar percent);

    /**
     * character used for a digit in a pattern.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getDigit(void) const;
    /**
     * character used for a digit in a pattern.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setDigit(UChar digit);

    /**
     * character used to separate positive and negative subpatterns
     * in a pattern.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getPatternSeparator(void) const;
    /**
     * character used to separate positive and negative subpatterns
     * in a pattern.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setPatternSeparator(UChar patternSeparator);

    /**
     * character used to represent infinity. Almost always left
     * unchanged.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UnicodeString& getInfinity(UnicodeString& result) const;
    /**
     * character used to represent infinity. Almost always left
     * unchanged.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setInfinity(const UnicodeString& infinity);
    /**
     * Checks to see if text at offset represents the inifinity string.
     * @return the number of characters used to represent infinity when 
     *      text starts with the inifinity string, otherwise it returns 0.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    int32_t compareInfinity(const UnicodeString& text, UTextOffset offset) const;

    /**
     * character used to represent NaN (Not A Number). Almost always left
     * unchanged.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UnicodeString& getNaN(UnicodeString& result) const;
    /**
     * character used to represent NaN. Almost always left
     * unchanged.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setNaN(const UnicodeString& NaN);
    /**
     * Checks to see if text at offset represents the NaN string.
     * @return the number of characters used to represent NaN when 
     *      text starts with the NaN string, otherwise it returns 0.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    int32_t compareNaN(const UnicodeString& text, UTextOffset offset) const;

    /**
     * character used to represent plus sign
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getPlusSign(void) const;
    /**
     * character used to represent plus sign
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setPlusSign(UChar minusSign);

    /**
     * character used to represent minus sign. If no explicit
     * negative format is specified, one is formed by prefixing
     * minusSign to the positive format.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getMinusSign(void) const;
    /**
     * character used to represent minus sign. If no explicit
     * negative format is specified, one is formed by prefixing
     * minusSign to the positive format.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setMinusSign(UChar minusSign);
 
    /**
     * character used to represent exponential. Almost always left
     * unchanged.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getExponentialSymbol(void) const;
    /**
     * character used to represent exponential. Almost always left
     * unchanged.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setExponentialSymbol(UChar exponential);

    /**
     * The string denoting the local currency.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UnicodeString& getCurrencySymbol(UnicodeString& result) const;
    /**
     * The string denoting the local currency.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setCurrencySymbol(const UnicodeString& currency);
    /**
     * Checks to see if text at offset represents the Currency Symbol string.
     * @return the number of characters used to represent Currency Symbol when
     *      text starts with the Currency Symbol string, otherwise it returns
     *      0.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    int32_t compareCurrencySymbol(const UnicodeString& text, UTextOffset offset) const;

    /**
     * The international string denoting the local currency.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UnicodeString& getInternationalCurrencySymbol(UnicodeString& result) const;
    /**
     * The international string denoting the local currency.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setInternationalCurrencySymbol(const UnicodeString& currency);
    /**
     * Checks to see if text at offset represents the International Currency
     * Symbol string.
     * @return the number of characters used to represent International
     *      Currency Symbol when text starts with the International Currency
     *      Symbol string, otherwise it returns 0.
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    int32_t compareInternationalCurrencySymbol(const UnicodeString& text, UTextOffset offset) const;

    /**
     * The monetary decimal separator.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getMonetaryDecimalSeparator(void) const;
    /**
     * The monetary decimal separator.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setMonetaryDecimalSeparator(UChar sep);

    /**
     * Return the character used to pad numbers out to a specified width.  This
     * is not the pad character itself; rather, it is the special pattern
     * character <em>preceding</em> the pad character.  In the pattern
     * "*_#,##0", '*' is the pad escape, and '_' is the pad character.
     * This function returns only the first code unit of the symbol string,
     * unlike getSymbol().
     * @return the character 
     * @see #setPadEscape
     * @see DecimalFormat#getFormatWidth
     * @see DecimalFormat#getPadPosition
     * @see DecimalFormat#getPadCharacter
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    UChar getPadEscape(void) const;

    /**
     * Set the character used to pad numbers out to a specified width.  This is
     * not the pad character itself; rather, it is the special pattern character
     * <em>preceding</em> the pad character.  In the pattern "*_#,##0", '*' is
     * the pad escape, and '_' is the pad character.
     * This function can set only a one-code unit symbol,
     * unlike setSymbol().
     * @see #getPadEscape
     * @see DecimalFormat#setFormatWidth
     * @see DecimalFormat#setPadPosition
     * @see DecimalFormat#setPadCharacter
     * @deprecated remove after 2000-dec-31. See UNumberFormatSymbol and unum_getSymbol() for a replacement.
     */
    void setPadEscape(UChar c);

private:
    /**
     * Initializes the symbols from the LocaleElements resource bundle.
     * Note: The organization of LocaleElements badly needs to be
     * cleaned up.
     */
    void initialize(const Locale& locale, UErrorCode& success, UBool useLastResortData = FALSE);

    /**
     * Initialize the symbols from the given array of UnicodeStrings.
     * The array must be of the correct size.
     */
    void initialize(const UnicodeString* numberElements, const UnicodeString* currencyElements);

    /**
     * Initialize the symbols with default values.
     */
    void initialize();

    UnicodeString fSymbols[kFormatSymbolCount];
};


// -------------------------------------

inline UnicodeString
DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
    if(symbol<kFormatSymbolCount) {
        return fSymbols[symbol];
    } else {
        return UnicodeString();
    }
}

// -------------------------------------

inline void
DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, UnicodeString value) {
    if(symbol<kFormatSymbolCount) {
        fSymbols[symbol]=value;
    }
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getZeroDigit() const
{
    return fSymbols[kZeroDigitSymbol].charAt(0);
}

// -------------------------------------
 
inline void
DecimalFormatSymbols::setZeroDigit(UChar zeroDigit)
{
    fSymbols[kZeroDigitSymbol] = zeroDigit;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getGroupingSeparator() const
{
    return fSymbols[kGroupingSeparatorSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setGroupingSeparator(UChar groupingSeparator)
{
    fSymbols[kGroupingSeparatorSymbol] = groupingSeparator;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getDecimalSeparator() const
{
    return fSymbols[kDecimalSeparatorSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setDecimalSeparator(UChar decimalSeparator)
{
    fSymbols[kDecimalSeparatorSymbol] = decimalSeparator;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getPerMill() const
{
    return fSymbols[kPermillSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setPerMill(UChar permill)
{
    fSymbols[kPermillSymbol] = permill;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getPercent() const
{
    return fSymbols[kPercentSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setPercent(UChar percent)
{
    fSymbols[kPercentSymbol] = percent;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getDigit() const
{
    return fSymbols[kDigitSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setDigit(UChar digit)
{
    fSymbols[kDigitSymbol] = digit;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getPatternSeparator() const
{
    return fSymbols[kPatternSeparatorSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setPatternSeparator(UChar patternSeparator)
{
    fSymbols[kPatternSeparatorSymbol] = patternSeparator;
}

// -------------------------------------

inline UnicodeString&
DecimalFormatSymbols::getInfinity(UnicodeString& result) const
{
    return result = fSymbols[kInfinitySymbol];
}

// -------------------------------------

inline void
DecimalFormatSymbols::setInfinity(const UnicodeString& infinity)
{
    fSymbols[kInfinitySymbol] = infinity;
}

// -------------------------------------

inline int32_t
DecimalFormatSymbols::compareInfinity(const UnicodeString& text,
                                      UTextOffset offset) const
{
    int32_t symbolLength = fSymbols[kInfinitySymbol].length();
    return text.compare(offset,
                        symbolLength,
                        fSymbols[kInfinitySymbol],
                        0,
                        symbolLength)
           ? 0 : symbolLength;
}

// -------------------------------------

inline UnicodeString&
DecimalFormatSymbols::getNaN(UnicodeString& result) const
{
    return result = fSymbols[kNaNSymbol];
}

// -------------------------------------

inline void
DecimalFormatSymbols::setNaN(const UnicodeString& NaN)
{
    fSymbols[kNaNSymbol] = NaN;
}

// -------------------------------------

inline int32_t
DecimalFormatSymbols::compareNaN(const UnicodeString& text, UTextOffset offset) const
{
    int32_t symbolLength = fSymbols[kNaNSymbol].length();
    return text.compare(offset,
                        symbolLength,
                        fSymbols[kNaNSymbol],
                        0,
                        symbolLength)
           ? 0 : symbolLength;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getPlusSign() const
{
    return fSymbols[kPlusSignSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setPlusSign(UChar plusSign)
{
    fSymbols[kPlusSignSymbol] = plusSign;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getMinusSign() const
{
    return fSymbols[kMinusSignSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setMinusSign(UChar minusSign)
{
    fSymbols[kMinusSignSymbol] = minusSign;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getExponentialSymbol(void) const
{
    return fSymbols[kExponentialSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setExponentialSymbol(UChar exponential)
{
    fSymbols[kExponentialSymbol] = exponential;
}

// -------------------------------------

inline UnicodeString&
DecimalFormatSymbols::getCurrencySymbol(UnicodeString& result) const
{
    return result = fSymbols[kCurrencySymbol];
}

// -------------------------------------

inline void
DecimalFormatSymbols::setCurrencySymbol(const UnicodeString& str)
{
    fSymbols[kCurrencySymbol] = str;
}

// -------------------------------------

inline int32_t
DecimalFormatSymbols::compareCurrencySymbol(const UnicodeString& text,
                                            UTextOffset offset) const
{
    int32_t symbolLength = fSymbols[kCurrencySymbol].length();
    return text.compare(offset,
                        symbolLength,
                        fSymbols[kCurrencySymbol],
                        0,
                        symbolLength)
           ? 0 : symbolLength;
}

// -------------------------------------

inline UnicodeString&
DecimalFormatSymbols::getInternationalCurrencySymbol(UnicodeString& result) const
{
    return result = fSymbols[kIntlCurrencySymbol];
}

// -------------------------------------

inline void
DecimalFormatSymbols::setInternationalCurrencySymbol(const UnicodeString& str)
{
    fSymbols[kIntlCurrencySymbol] = str;
}

// -------------------------------------

inline int32_t
DecimalFormatSymbols::compareInternationalCurrencySymbol(const UnicodeString& text,
                                                         UTextOffset offset) const
{
    int32_t symbolLength = fSymbols[kIntlCurrencySymbol].length();
    return text.compare(offset,
                        symbolLength,
                        fSymbols[kIntlCurrencySymbol],
                        0,
                        symbolLength)
           ? 0 : symbolLength;
}

// -------------------------------------

inline UChar
DecimalFormatSymbols::getMonetaryDecimalSeparator(void) const
{
    return fSymbols[kMonetarySeparatorSymbol].charAt(0);
}

// -------------------------------------

inline void
DecimalFormatSymbols::setMonetaryDecimalSeparator(UChar sep)
{
    fSymbols[kMonetarySeparatorSymbol] = sep;
}

inline UChar DecimalFormatSymbols::getPadEscape(void) const {
    return fSymbols[kPadEscapeSymbol].charAt(0);
}

inline void DecimalFormatSymbols::setPadEscape(UChar c) {
    fSymbols[kPadEscapeSymbol] = c;
}

#endif // _DCFMTSYM
//eof
