1/*
2*******************************************************************************
3* Copyright (C) 2007-2013, International Business Machines Corporation and
4* others. All Rights Reserved.
5*******************************************************************************
6*
7
8* File PLURFMT.H
9********************************************************************************
10*/
11
12#ifndef PLURFMT
13#define PLURFMT
14
15#include "unicode/utypes.h"
16
17/**
18 * \file
19 * \brief C++ API: PluralFormat object
20 */
21
22#if !UCONFIG_NO_FORMATTING
23
24#include "unicode/messagepattern.h"
25#include "unicode/numfmt.h"
26#include "unicode/plurrule.h"
27
28U_NAMESPACE_BEGIN
29
30class Hashtable;
31
32/**
33 * <p>
34 * <code>PluralFormat</code> supports the creation of internationalized
35 * messages with plural inflection. It is based on <i>plural
36 * selection</i>, i.e. the caller specifies messages for each
37 * plural case that can appear in the user's language and the
38 * <code>PluralFormat</code> selects the appropriate message based on
39 * the number.
40 * </p>
41 * <h4>The Problem of Plural Forms in Internationalized Messages</h4>
42 * <p>
43 * Different languages have different ways to inflect
44 * plurals. Creating internationalized messages that include plural
45 * forms is only feasible when the framework is able to handle plural
46 * forms of <i>all</i> languages correctly. <code>ChoiceFormat</code>
47 * doesn't handle this well, because it attaches a number interval to
48 * each message and selects the message whose interval contains a
49 * given number. This can only handle a finite number of
50 * intervals. But in some languages, like Polish, one plural case
51 * applies to infinitely many intervals (e.g., the plural case applies to
52 * numbers ending with 2, 3, or 4 except those ending with 12, 13, or
53 * 14). Thus <code>ChoiceFormat</code> is not adequate.
54 * </p><p>
55 * <code>PluralFormat</code> deals with this by breaking the problem
56 * into two parts:
57 * <ul>
58 * <li>It uses <code>PluralRules</code> that can define more complex
59 *     conditions for a plural case than just a single interval. These plural
60 *     rules define both what plural cases exist in a language, and to
61 *     which numbers these cases apply.
62 * <li>It provides predefined plural rules for many languages. Thus, the programmer
63 *     need not worry about the plural cases of a language and
64 *     does not have to define the plural cases; they can simply
65 *     use the predefined keywords. The whole plural formatting of messages can
66 *     be done using localized patterns from resource bundles. For predefined plural
67 *     rules, see the CLDR <i>Language Plural Rules</i> page at
68 *    http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
69 * </ul>
70 * </p>
71 * <h4>Usage of <code>PluralFormat</code></h4>
72 * <p>Note: Typically, plural formatting is done via <code>MessageFormat</code>
73 * with a <code>plural</code> argument type,
74 * rather than using a stand-alone <code>PluralFormat</code>.
75 * </p><p>
76 * This discussion assumes that you use <code>PluralFormat</code> with
77 * a predefined set of plural rules. You can create one using one of
78 * the constructors that takes a <code>locale</code> object. To
79 * specify the message pattern, you can either pass it to the
80 * constructor or set it explicitly using the
81 * <code>applyPattern()</code> method. The <code>format()</code>
82 * method takes a number object and selects the message of the
83 * matching plural case. This message will be returned.
84 * </p>
85 * <h5>Patterns and Their Interpretation</h5>
86 * <p>
87 * The pattern text defines the message output for each plural case of the
88 * specified locale. Syntax:
89 * <pre>
90 * pluralStyle = [offsetValue] (selector '{' message '}')+
91 * offsetValue = "offset:" number
92 * selector = explicitValue | keyword
93 * explicitValue = '=' number  // adjacent, no white space in between
94 * keyword = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
95 * message: see {@link MessageFormat}
96 * </pre>
97 * Pattern_White_Space between syntax elements is ignored, except
98 * between the {curly braces} and their sub-message,
99 * and between the '=' and the number of an explicitValue.
100 *
101 * </p><p>
102 * There are 6 predefined casekeyword in CLDR/ICU - 'zero', 'one', 'two', 'few', 'many' and
103 * 'other'. You always have to define a message text for the default plural case
104 * <code>other</code> which is contained in every rule set.
105 * If you do not specify a message text for a particular plural case, the
106 * message text of the plural case <code>other</code> gets assigned to this
107 * plural case.
108 * </p><p>
109 * When formatting, the input number is first matched against the explicitValue clauses.
110 * If there is no exact-number match, then a keyword is selected by calling
111 * the <code>PluralRules</code> with the input number <em>minus the offset</em>.
112 * (The offset defaults to 0 if it is omitted from the pattern string.)
113 * If there is no clause with that keyword, then the "other" clauses is returned.
114 * </p><p>
115 * An unquoted pound sign (<code>#</code>) in the selected sub-message
116 * itself (i.e., outside of arguments nested in the sub-message)
117 * is replaced by the input number minus the offset.
118 * The number-minus-offset value is formatted using a
119 * <code>NumberFormat</code> for the <code>PluralFormat</code>'s locale. If you
120 * need special number formatting, you have to use a <code>MessageFormat</code>
121 * and explicitly specify a <code>NumberFormat</code> argument.
122 * <strong>Note:</strong> That argument is formatting without subtracting the offset!
123 * If you need a custom format and have a non-zero offset, then you need to pass the
124 * number-minus-offset value as a separate parameter.
125 * </p>
126 * For a usage example, see the {@link MessageFormat} class documentation.
127 *
128 * <h4>Defining Custom Plural Rules</h4>
129 * <p>If you need to use <code>PluralFormat</code> with custom rules, you can
130 * create a <code>PluralRules</code> object and pass it to
131 * <code>PluralFormat</code>'s constructor. If you also specify a locale in this
132 * constructor, this locale will be used to format the number in the message
133 * texts.
134 * </p><p>
135 * For more information about <code>PluralRules</code>, see
136 * {@link PluralRules}.
137 * </p>
138 *
139 * ported from Java
140 * @stable ICU 4.0
141 */
142
143class U_I18N_API PluralFormat : public Format {
144public:
145
146    /**
147     * Creates a new cardinal-number <code>PluralFormat</code> for the default locale.
148     * This locale will be used to get the set of plural rules and for standard
149     * number formatting.
150     * @param status  output param set to success/failure code on exit, which
151     *                must not indicate a failure before the function call.
152     * @stable ICU 4.0
153     */
154    PluralFormat(UErrorCode& status);
155
156    /**
157     * Creates a new cardinal-number <code>PluralFormat</code> for a given locale.
158     * @param locale the <code>PluralFormat</code> will be configured with
159     *               rules for this locale. This locale will also be used for
160     *               standard number formatting.
161     * @param status output param set to success/failure code on exit, which
162     *               must not indicate a failure before the function call.
163     * @stable ICU 4.0
164     */
165    PluralFormat(const Locale& locale, UErrorCode& status);
166
167    /**
168     * Creates a new <code>PluralFormat</code> for a given set of rules.
169     * The standard number formatting will be done using the default locale.
170     * @param rules   defines the behavior of the <code>PluralFormat</code>
171     *                object.
172     * @param status  output param set to success/failure code on exit, which
173     *                must not indicate a failure before the function call.
174     * @stable ICU 4.0
175     */
176    PluralFormat(const PluralRules& rules, UErrorCode& status);
177
178    /**
179     * Creates a new <code>PluralFormat</code> for a given set of rules.
180     * The standard number formatting will be done using the given locale.
181     * @param locale  the default number formatting will be done using this
182     *                locale.
183     * @param rules   defines the behavior of the <code>PluralFormat</code>
184     *                object.
185     * @param status  output param set to success/failure code on exit, which
186     *                must not indicate a failure before the function call.
187     * @stable ICU 4.0
188	 * <p>
189	 * <h4>Sample code</h4>
190	 * \snippet samples/plurfmtsample/plurfmtsample.cpp PluralFormatExample1
191	 * \snippet samples/plurfmtsample/plurfmtsample.cpp PluralFormatExample
192	 * <p>
193     */
194    PluralFormat(const Locale& locale, const PluralRules& rules, UErrorCode& status);
195
196    /**
197     * Creates a new <code>PluralFormat</code> for the plural type.
198     * The standard number formatting will be done using the given locale.
199     * @param locale  the default number formatting will be done using this
200     *                locale.
201     * @param type    The plural type (e.g., cardinal or ordinal).
202     * @param status  output param set to success/failure code on exit, which
203     *                must not indicate a failure before the function call.
204     * @stable ICU 50
205     */
206    PluralFormat(const Locale& locale, UPluralType type, UErrorCode& status);
207
208    /**
209     * Creates a new cardinal-number <code>PluralFormat</code> for a given pattern string.
210     * The default locale will be used to get the set of plural rules and for
211     * standard number formatting.
212     * @param  pattern the pattern for this <code>PluralFormat</code>.
213     *                 errors are returned to status if the pattern is invalid.
214     * @param status   output param set to success/failure code on exit, which
215     *                 must not indicate a failure before the function call.
216     * @stable ICU 4.0
217     */
218    PluralFormat(const UnicodeString& pattern, UErrorCode& status);
219
220    /**
221     * Creates a new cardinal-number <code>PluralFormat</code> for a given pattern string and
222     * locale.
223     * The locale will be used to get the set of plural rules and for
224     * standard number formatting.
225     * @param locale   the <code>PluralFormat</code> will be configured with
226     *                 rules for this locale. This locale will also be used for
227     *                 standard number formatting.
228     * @param pattern  the pattern for this <code>PluralFormat</code>.
229     *                 errors are returned to status if the pattern is invalid.
230     * @param status   output param set to success/failure code on exit, which
231     *                 must not indicate a failure before the function call.
232     * @stable ICU 4.0
233     */
234    PluralFormat(const Locale& locale, const UnicodeString& pattern, UErrorCode& status);
235
236    /**
237     * Creates a new <code>PluralFormat</code> for a given set of rules, a
238     * pattern and a locale.
239     * @param rules    defines the behavior of the <code>PluralFormat</code>
240     *                 object.
241     * @param pattern  the pattern for this <code>PluralFormat</code>.
242     *                 errors are returned to status if the pattern is invalid.
243     * @param status   output param set to success/failure code on exit, which
244     *                 must not indicate a failure before the function call.
245     * @stable ICU 4.0
246     */
247    PluralFormat(const PluralRules& rules,
248                 const UnicodeString& pattern,
249                 UErrorCode& status);
250
251    /**
252     * Creates a new <code>PluralFormat</code> for a given set of rules, a
253     * pattern and a locale.
254     * @param locale  the <code>PluralFormat</code> will be configured with
255     *                rules for this locale. This locale will also be used for
256     *                standard number formatting.
257     * @param rules   defines the behavior of the <code>PluralFormat</code>
258     *                object.
259     * @param pattern the pattern for this <code>PluralFormat</code>.
260     *                errors are returned to status if the pattern is invalid.
261     * @param status  output param set to success/failure code on exit, which
262     *                must not indicate a failure before the function call.
263     * @stable ICU 4.0
264     */
265    PluralFormat(const Locale& locale,
266                 const PluralRules& rules,
267                 const UnicodeString& pattern,
268                 UErrorCode& status);
269
270    /**
271     * Creates a new <code>PluralFormat</code> for a plural type, a
272     * pattern and a locale.
273     * @param locale  the <code>PluralFormat</code> will be configured with
274     *                rules for this locale. This locale will also be used for
275     *                standard number formatting.
276     * @param type    The plural type (e.g., cardinal or ordinal).
277     * @param pattern the pattern for this <code>PluralFormat</code>.
278     *                errors are returned to status if the pattern is invalid.
279     * @param status  output param set to success/failure code on exit, which
280     *                must not indicate a failure before the function call.
281     * @stable ICU 50
282     */
283    PluralFormat(const Locale& locale,
284                 UPluralType type,
285                 const UnicodeString& pattern,
286                 UErrorCode& status);
287
288    /**
289      * copy constructor.
290      * @stable ICU 4.0
291      */
292    PluralFormat(const PluralFormat& other);
293
294    /**
295     * Destructor.
296     * @stable ICU 4.0
297     */
298    virtual ~PluralFormat();
299
300    /**
301     * Sets the pattern used by this plural format.
302     * The method parses the pattern and creates a map of format strings
303     * for the plural rules.
304     * Patterns and their interpretation are specified in the class description.
305     *
306     * @param pattern the pattern for this plural format
307     *                errors are returned to status if the pattern is invalid.
308     * @param status  output param set to success/failure code on exit, which
309     *                must not indicate a failure before the function call.
310     * @stable ICU 4.0
311     */
312    void applyPattern(const UnicodeString& pattern, UErrorCode& status);
313
314
315    using Format::format;
316
317    /**
318     * Formats a plural message for a given number.
319     *
320     * @param number  a number for which the plural message should be formatted
321     *                for. If no pattern has been applied to this
322     *                <code>PluralFormat</code> object yet, the formatted number
323     *                will be returned.
324     * @param status  output param set to success/failure code on exit, which
325     *                must not indicate a failure before the function call.
326     * @return        the string containing the formatted plural message.
327     * @stable ICU 4.0
328     */
329    UnicodeString format(int32_t number, UErrorCode& status) const;
330
331    /**
332     * Formats a plural message for a given number.
333     *
334     * @param number  a number for which the plural message should be formatted
335     *                for. If no pattern has been applied to this
336     *                PluralFormat object yet, the formatted number
337     *                will be returned.
338     * @param status  output param set to success or failure code on exit, which
339     *                must not indicate a failure before the function call.
340     * @return        the string containing the formatted plural message.
341     * @stable ICU 4.0
342     */
343    UnicodeString format(double number, UErrorCode& status) const;
344
345    /**
346     * Formats a plural message for a given number.
347     *
348     * @param number   a number for which the plural message should be formatted
349     *                 for. If no pattern has been applied to this
350     *                 <code>PluralFormat</code> object yet, the formatted number
351     *                 will be returned.
352     * @param appendTo output parameter to receive result.
353     *                 result is appended to existing contents.
354     * @param pos      On input: an alignment field, if desired.
355     *                 On output: the offsets of the alignment field.
356     * @param status   output param set to success/failure code on exit, which
357     *                 must not indicate a failure before the function call.
358     * @return         the string containing the formatted plural message.
359     * @stable ICU 4.0
360     */
361    UnicodeString& format(int32_t number,
362                          UnicodeString& appendTo,
363                          FieldPosition& pos,
364                          UErrorCode& status) const;
365
366    /**
367     * Formats a plural message for a given number.
368     *
369     * @param number   a number for which the plural message should be formatted
370     *                 for. If no pattern has been applied to this
371     *                 PluralFormat object yet, the formatted number
372     *                 will be returned.
373     * @param appendTo output parameter to receive result.
374     *                 result is appended to existing contents.
375     * @param pos      On input: an alignment field, if desired.
376     *                 On output: the offsets of the alignment field.
377     * @param status   output param set to success/failure code on exit, which
378     *                 must not indicate a failure before the function call.
379     * @return         the string containing the formatted plural message.
380     * @stable ICU 4.0
381     */
382    UnicodeString& format(double number,
383                          UnicodeString& appendTo,
384                          FieldPosition& pos,
385                          UErrorCode& status) const;
386
387#ifndef U_HIDE_DEPRECATED_API
388    /**
389     * Sets the locale used by this <code>PluraFormat</code> object.
390     * Note: Calling this method resets this <code>PluraFormat</code> object,
391     *     i.e., a pattern that was applied previously will be removed,
392     *     and the NumberFormat is set to the default number format for
393     *     the locale.  The resulting format behaves the same as one
394     *     constructed from {@link #PluralFormat(const Locale& locale, UPluralType type, UErrorCode& status)}
395     *     with UPLURAL_TYPE_CARDINAL.
396     * @param locale  the <code>locale</code> to use to configure the formatter.
397     * @param status  output param set to success/failure code on exit, which
398     *                must not indicate a failure before the function call.
399     * @deprecated ICU 50 This method clears the pattern and might create
400     *             a different kind of PluralRules instance;
401     *             use one of the constructors to create a new instance instead.
402     */
403    void setLocale(const Locale& locale, UErrorCode& status);
404#endif  /* U_HIDE_DEPRECATED_API */
405
406    /**
407      * Sets the number format used by this formatter.  You only need to
408      * call this if you want a different number format than the default
409      * formatter for the locale.
410      * @param format  the number format to use.
411      * @param status  output param set to success/failure code on exit, which
412      *                must not indicate a failure before the function call.
413      * @stable ICU 4.0
414      */
415    void setNumberFormat(const NumberFormat* format, UErrorCode& status);
416
417    /**
418       * Assignment operator
419       *
420       * @param other    the PluralFormat object to copy from.
421       * @stable ICU 4.0
422       */
423    PluralFormat& operator=(const PluralFormat& other);
424
425    /**
426      * Return true if another object is semantically equal to this one.
427      *
428      * @param other    the PluralFormat object to be compared with.
429      * @return         true if other is semantically equal to this.
430      * @stable ICU 4.0
431      */
432    virtual UBool operator==(const Format& other) const;
433
434    /**
435     * Return true if another object is semantically unequal to this one.
436     *
437     * @param other    the PluralFormat object to be compared with.
438     * @return         true if other is semantically unequal to this.
439     * @stable ICU 4.0
440     */
441    virtual UBool operator!=(const Format& other) const;
442
443    /**
444     * Clones this Format object polymorphically.  The caller owns the
445     * result and should delete it when done.
446     * @stable ICU 4.0
447     */
448    virtual Format* clone(void) const;
449
450   /**
451    * Formats a plural message for a number taken from a Formattable object.
452    *
453    * @param obj       The object containing a number for which the
454    *                  plural message should be formatted.
455    *                  The object must be of a numeric type.
456    * @param appendTo  output parameter to receive result.
457    *                  Result is appended to existing contents.
458    * @param pos       On input: an alignment field, if desired.
459    *                  On output: the offsets of the alignment field.
460    * @param status    output param filled with success/failure status.
461    * @return          Reference to 'appendTo' parameter.
462    * @stable ICU 4.0
463    */
464   UnicodeString& format(const Formattable& obj,
465                         UnicodeString& appendTo,
466                         FieldPosition& pos,
467                         UErrorCode& status) const;
468
469   /**
470    * Returns the pattern from applyPattern() or constructor().
471    *
472    * @param  appendTo  output parameter to receive result.
473     *                  Result is appended to existing contents.
474    * @return the UnicodeString with inserted pattern.
475    * @stable ICU 4.0
476    */
477   UnicodeString& toPattern(UnicodeString& appendTo);
478
479   /**
480    * This method is not yet supported by <code>PluralFormat</code>.
481    * <P>
482    * Before calling, set parse_pos.index to the offset you want to start
483    * parsing at in the source. After calling, parse_pos.index is the end of
484    * the text you parsed. If error occurs, index is unchanged.
485    * <P>
486    * When parsing, leading whitespace is discarded (with a successful parse),
487    * while trailing whitespace is left as is.
488    * <P>
489    * See Format::parseObject() for more.
490    *
491    * @param source    The string to be parsed into an object.
492    * @param result    Formattable to be set to the parse result.
493    *                  If parse fails, return contents are undefined.
494    * @param parse_pos The position to start parsing at. Upon return
495    *                  this param is set to the position after the
496    *                  last character successfully parsed. If the
497    *                  source is not parsed successfully, this param
498    *                  will remain unchanged.
499    * @stable ICU 4.0
500    */
501   virtual void parseObject(const UnicodeString& source,
502                            Formattable& result,
503                            ParsePosition& parse_pos) const;
504
505    /**
506     * ICU "poor man's RTTI", returns a UClassID for this class.
507     *
508     * @stable ICU 4.0
509     *
510     */
511    static UClassID U_EXPORT2 getStaticClassID(void);
512
513    /**
514     * ICU "poor man's RTTI", returns a UClassID for the actual class.
515     *
516     * @stable ICU 4.0
517     */
518     virtual UClassID getDynamicClassID() const;
519
520#if (defined(__xlC__) && (__xlC__ < 0x0C00)) || (U_PLATFORM == U_PF_OS390) || (U_PLATFORM ==U_PF_OS400)
521// Work around a compiler bug on xlC 11.1 on AIX 7.1 that would
522// prevent PluralSelectorAdapter from implementing private PluralSelector.
523// xlC error message:
524// 1540-0300 (S) The "private" member "class icu_49::PluralFormat::PluralSelector" cannot be accessed.
525public:
526#else
527private:
528#endif
529     /**
530      * @internal
531      */
532    class U_I18N_API PluralSelector : public UMemory {
533      public:
534        virtual ~PluralSelector();
535        /**
536         * Given a number, returns the appropriate PluralFormat keyword.
537         *
538         * @param context worker object for the selector.
539         * @param number The number to be plural-formatted.
540         * @param ec Error code.
541         * @return The selected PluralFormat keyword.
542         * @internal
543         */
544        virtual UnicodeString select(void *context, double number, UErrorCode& ec) const = 0;
545    };
546
547    /**
548     * @internal
549     */
550    class U_I18N_API PluralSelectorAdapter : public PluralSelector {
551      public:
552        PluralSelectorAdapter() : pluralRules(NULL) {
553        }
554
555        virtual ~PluralSelectorAdapter();
556
557        virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const; /**< @internal */
558
559        void reset();
560
561        PluralRules* pluralRules;
562    };
563
564#if defined(__xlC__)
565// End of xlC bug workaround, keep remaining definitions private.
566private:
567#endif
568    Locale  locale;
569    MessagePattern msgPattern;
570    NumberFormat*  numberFormat;
571    double offset;
572    PluralSelectorAdapter pluralRulesWrapper;
573
574    PluralFormat();   // default constructor not implemented
575    void init(const PluralRules* rules, UPluralType type, UErrorCode& status);
576    /**
577     * Copies dynamically allocated values (pointer fields).
578     * Others are copied using their copy constructors and assignment operators.
579     */
580    void copyObjects(const PluralFormat& other);
581
582    UnicodeString& format(const Formattable& numberObject, double number,
583                          UnicodeString& appendTo,
584                          FieldPosition& pos,
585                          UErrorCode& status) const; /**< @internal */
586
587    /**
588     * Finds the PluralFormat sub-message for the given number, or the "other" sub-message.
589     * @param pattern A MessagePattern.
590     * @param partIndex the index of the first PluralFormat argument style part.
591     * @param selector the PluralSelector for mapping the number (minus offset) to a keyword.
592     * @param context worker object for the selector.
593     * @param number a number to be matched to one of the PluralFormat argument's explicit values,
594     *        or mapped via the PluralSelector.
595     * @param ec ICU error code.
596     * @return the sub-message start part index.
597     */
598    static int32_t findSubMessage(
599         const MessagePattern& pattern, int32_t partIndex,
600         const PluralSelector& selector, void *context, double number, UErrorCode& ec); /**< @internal */
601
602    friend class MessageFormat;
603};
604
605U_NAMESPACE_END
606
607#endif /* #if !UCONFIG_NO_FORMATTING */
608
609#endif // _PLURFMT
610//eof
611