|
|
|||
File indexing completed on 2026-01-03 10:24:02
0001 // © 2016 and later: Unicode, Inc. and others. 0002 // License & terms of use: http://www.unicode.org/copyright.html 0003 /* 0004 ******************************************************************************* 0005 * Copyright (C) 2007-2014, International Business Machines Corporation and 0006 * others. All Rights Reserved. 0007 ******************************************************************************* 0008 * 0009 0010 * File PLURFMT.H 0011 ******************************************************************************** 0012 */ 0013 0014 #ifndef PLURFMT 0015 #define PLURFMT 0016 0017 #include "unicode/utypes.h" 0018 0019 #if U_SHOW_CPLUSPLUS_API 0020 0021 /** 0022 * \file 0023 * \brief C++ API: PluralFormat object 0024 */ 0025 0026 #if !UCONFIG_NO_FORMATTING 0027 0028 #include "unicode/messagepattern.h" 0029 #include "unicode/numfmt.h" 0030 #include "unicode/plurrule.h" 0031 0032 U_NAMESPACE_BEGIN 0033 0034 class Hashtable; 0035 class NFRule; 0036 0037 /** 0038 * <p> 0039 * <code>PluralFormat</code> supports the creation of internationalized 0040 * messages with plural inflection. It is based on <i>plural 0041 * selection</i>, i.e. the caller specifies messages for each 0042 * plural case that can appear in the user's language and the 0043 * <code>PluralFormat</code> selects the appropriate message based on 0044 * the number. 0045 * </p> 0046 * <h4>The Problem of Plural Forms in Internationalized Messages</h4> 0047 * <p> 0048 * Different languages have different ways to inflect 0049 * plurals. Creating internationalized messages that include plural 0050 * forms is only feasible when the framework is able to handle plural 0051 * forms of <i>all</i> languages correctly. <code>ChoiceFormat</code> 0052 * doesn't handle this well, because it attaches a number interval to 0053 * each message and selects the message whose interval contains a 0054 * given number. This can only handle a finite number of 0055 * intervals. But in some languages, like Polish, one plural case 0056 * applies to infinitely many intervals (e.g., the plural case applies to 0057 * numbers ending with 2, 3, or 4 except those ending with 12, 13, or 0058 * 14). Thus <code>ChoiceFormat</code> is not adequate. 0059 * </p><p> 0060 * <code>PluralFormat</code> deals with this by breaking the problem 0061 * into two parts: 0062 * <ul> 0063 * <li>It uses <code>PluralRules</code> that can define more complex 0064 * conditions for a plural case than just a single interval. These plural 0065 * rules define both what plural cases exist in a language, and to 0066 * which numbers these cases apply. 0067 * <li>It provides predefined plural rules for many languages. Thus, the programmer 0068 * need not worry about the plural cases of a language and 0069 * does not have to define the plural cases; they can simply 0070 * use the predefined keywords. The whole plural formatting of messages can 0071 * be done using localized patterns from resource bundles. For predefined plural 0072 * rules, see the CLDR <i>Language Plural Rules</i> page at 0073 * https://unicode-org.github.io/cldr-staging/charts/latest/supplemental/language_plural_rules.html 0074 * </ul> 0075 * </p> 0076 * <h4>Usage of <code>PluralFormat</code></h4> 0077 * <p>Note: Typically, plural formatting is done via <code>MessageFormat</code> 0078 * with a <code>plural</code> argument type, 0079 * rather than using a stand-alone <code>PluralFormat</code>. 0080 * </p><p> 0081 * This discussion assumes that you use <code>PluralFormat</code> with 0082 * a predefined set of plural rules. You can create one using one of 0083 * the constructors that takes a <code>locale</code> object. To 0084 * specify the message pattern, you can either pass it to the 0085 * constructor or set it explicitly using the 0086 * <code>applyPattern()</code> method. The <code>format()</code> 0087 * method takes a number object and selects the message of the 0088 * matching plural case. This message will be returned. 0089 * </p> 0090 * <h5>Patterns and Their Interpretation</h5> 0091 * <p> 0092 * The pattern text defines the message output for each plural case of the 0093 * specified locale. Syntax: 0094 * <pre> 0095 * pluralStyle = [offsetValue] (selector '{' message '}')+ 0096 * offsetValue = "offset:" number 0097 * selector = explicitValue | keyword 0098 * explicitValue = '=' number // adjacent, no white space in between 0099 * keyword = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+ 0100 * message: see {@link MessageFormat} 0101 * </pre> 0102 * Pattern_White_Space between syntax elements is ignored, except 0103 * between the {curly braces} and their sub-message, 0104 * and between the '=' and the number of an explicitValue. 0105 * 0106 * </p><p> 0107 * There are 6 predefined casekeyword in CLDR/ICU - 'zero', 'one', 'two', 'few', 'many' and 0108 * 'other'. You always have to define a message text for the default plural case 0109 * <code>other</code> which is contained in every rule set. 0110 * If you do not specify a message text for a particular plural case, the 0111 * message text of the plural case <code>other</code> gets assigned to this 0112 * plural case. 0113 * </p><p> 0114 * When formatting, the input number is first matched against the explicitValue clauses. 0115 * If there is no exact-number match, then a keyword is selected by calling 0116 * the <code>PluralRules</code> with the input number <em>minus the offset</em>. 0117 * (The offset defaults to 0 if it is omitted from the pattern string.) 0118 * If there is no clause with that keyword, then the "other" clauses is returned. 0119 * </p><p> 0120 * An unquoted pound sign (<code>#</code>) in the selected sub-message 0121 * itself (i.e., outside of arguments nested in the sub-message) 0122 * is replaced by the input number minus the offset. 0123 * The number-minus-offset value is formatted using a 0124 * <code>NumberFormat</code> for the <code>PluralFormat</code>'s locale. If you 0125 * need special number formatting, you have to use a <code>MessageFormat</code> 0126 * and explicitly specify a <code>NumberFormat</code> argument. 0127 * <strong>Note:</strong> That argument is formatting without subtracting the offset! 0128 * If you need a custom format and have a non-zero offset, then you need to pass the 0129 * number-minus-offset value as a separate parameter. 0130 * </p> 0131 * For a usage example, see the {@link MessageFormat} class documentation. 0132 * 0133 * <h4>Defining Custom Plural Rules</h4> 0134 * <p>If you need to use <code>PluralFormat</code> with custom rules, you can 0135 * create a <code>PluralRules</code> object and pass it to 0136 * <code>PluralFormat</code>'s constructor. If you also specify a locale in this 0137 * constructor, this locale will be used to format the number in the message 0138 * texts. 0139 * </p><p> 0140 * For more information about <code>PluralRules</code>, see 0141 * {@link PluralRules}. 0142 * </p> 0143 * 0144 * ported from Java 0145 * @stable ICU 4.0 0146 */ 0147 0148 class U_I18N_API PluralFormat : public Format { 0149 public: 0150 0151 /** 0152 * Creates a new cardinal-number <code>PluralFormat</code> for the default locale. 0153 * This locale will be used to get the set of plural rules and for standard 0154 * number formatting. 0155 * @param status output param set to success/failure code on exit, which 0156 * must not indicate a failure before the function call. 0157 * @stable ICU 4.0 0158 */ 0159 PluralFormat(UErrorCode& status); 0160 0161 /** 0162 * Creates a new cardinal-number <code>PluralFormat</code> for a given locale. 0163 * @param locale the <code>PluralFormat</code> will be configured with 0164 * rules for this locale. This locale will also be used for 0165 * standard number formatting. 0166 * @param status output param set to success/failure code on exit, which 0167 * must not indicate a failure before the function call. 0168 * @stable ICU 4.0 0169 */ 0170 PluralFormat(const Locale& locale, UErrorCode& status); 0171 0172 /** 0173 * Creates a new <code>PluralFormat</code> for a given set of rules. 0174 * The standard number formatting will be done using the default locale. 0175 * @param rules defines the behavior of the <code>PluralFormat</code> 0176 * object. 0177 * @param status output param set to success/failure code on exit, which 0178 * must not indicate a failure before the function call. 0179 * @stable ICU 4.0 0180 */ 0181 PluralFormat(const PluralRules& rules, UErrorCode& status); 0182 0183 /** 0184 * Creates a new <code>PluralFormat</code> for a given set of rules. 0185 * The standard number formatting will be done using the given locale. 0186 * @param locale the default number formatting will be done using this 0187 * locale. 0188 * @param rules defines the behavior of the <code>PluralFormat</code> 0189 * object. 0190 * @param status output param set to success/failure code on exit, which 0191 * must not indicate a failure before the function call. 0192 * @stable ICU 4.0 0193 */ 0194 PluralFormat(const Locale& locale, const PluralRules& rules, UErrorCode& status); 0195 0196 /** 0197 * Creates a new <code>PluralFormat</code> for the plural type. 0198 * The standard number formatting will be done using the given locale. 0199 * @param locale the default number formatting will be done using this 0200 * locale. 0201 * @param type The plural type (e.g., cardinal or ordinal). 0202 * @param status output param set to success/failure code on exit, which 0203 * must not indicate a failure before the function call. 0204 * @stable ICU 50 0205 */ 0206 PluralFormat(const Locale& locale, UPluralType type, UErrorCode& status); 0207 0208 /** 0209 * Creates a new cardinal-number <code>PluralFormat</code> for a given pattern string. 0210 * The default locale will be used to get the set of plural rules and for 0211 * standard number formatting. 0212 * @param pattern the pattern for this <code>PluralFormat</code>. 0213 * errors are returned to status if the pattern is invalid. 0214 * @param status output param set to success/failure code on exit, which 0215 * must not indicate a failure before the function call. 0216 * @stable ICU 4.0 0217 */ 0218 PluralFormat(const UnicodeString& pattern, UErrorCode& status); 0219 0220 /** 0221 * Creates a new cardinal-number <code>PluralFormat</code> for a given pattern string and 0222 * locale. 0223 * The locale will be used to get the set of plural rules and for 0224 * standard number formatting. 0225 * @param locale the <code>PluralFormat</code> will be configured with 0226 * rules for this locale. This locale will also be used for 0227 * standard number formatting. 0228 * @param pattern the pattern for this <code>PluralFormat</code>. 0229 * errors are returned to status if the pattern is invalid. 0230 * @param status output param set to success/failure code on exit, which 0231 * must not indicate a failure before the function call. 0232 * @stable ICU 4.0 0233 */ 0234 PluralFormat(const Locale& locale, const UnicodeString& pattern, UErrorCode& status); 0235 0236 /** 0237 * Creates a new <code>PluralFormat</code> for a given set of rules, a 0238 * pattern and a locale. 0239 * @param rules defines the behavior of the <code>PluralFormat</code> 0240 * object. 0241 * @param pattern the pattern for this <code>PluralFormat</code>. 0242 * errors are returned to status if the pattern is invalid. 0243 * @param status output param set to success/failure code on exit, which 0244 * must not indicate a failure before the function call. 0245 * @stable ICU 4.0 0246 */ 0247 PluralFormat(const PluralRules& rules, 0248 const UnicodeString& pattern, 0249 UErrorCode& status); 0250 0251 /** 0252 * Creates a new <code>PluralFormat</code> for a given set of rules, a 0253 * pattern and a locale. 0254 * @param locale the <code>PluralFormat</code> will be configured with 0255 * rules for this locale. This locale will also be used for 0256 * standard number formatting. 0257 * @param rules defines the behavior of the <code>PluralFormat</code> 0258 * object. 0259 * @param pattern the pattern for this <code>PluralFormat</code>. 0260 * errors are returned to status if the pattern is invalid. 0261 * @param status output param set to success/failure code on exit, which 0262 * must not indicate a failure before the function call. 0263 * @stable ICU 4.0 0264 */ 0265 PluralFormat(const Locale& locale, 0266 const PluralRules& rules, 0267 const UnicodeString& pattern, 0268 UErrorCode& status); 0269 0270 /** 0271 * Creates a new <code>PluralFormat</code> for a plural type, a 0272 * pattern and a locale. 0273 * @param locale the <code>PluralFormat</code> will be configured with 0274 * rules for this locale. This locale will also be used for 0275 * standard number formatting. 0276 * @param type The plural type (e.g., cardinal or ordinal). 0277 * @param pattern the pattern for this <code>PluralFormat</code>. 0278 * errors are returned to status if the pattern is invalid. 0279 * @param status output param set to success/failure code on exit, which 0280 * must not indicate a failure before the function call. 0281 * @stable ICU 50 0282 */ 0283 PluralFormat(const Locale& locale, 0284 UPluralType type, 0285 const UnicodeString& pattern, 0286 UErrorCode& status); 0287 0288 /** 0289 * copy constructor. 0290 * @stable ICU 4.0 0291 */ 0292 PluralFormat(const PluralFormat& other); 0293 0294 /** 0295 * Destructor. 0296 * @stable ICU 4.0 0297 */ 0298 virtual ~PluralFormat(); 0299 0300 /** 0301 * Sets the pattern used by this plural format. 0302 * The method parses the pattern and creates a map of format strings 0303 * for the plural rules. 0304 * Patterns and their interpretation are specified in the class description. 0305 * 0306 * @param pattern the pattern for this plural format 0307 * errors are returned to status if the pattern is invalid. 0308 * @param status output param set to success/failure code on exit, which 0309 * must not indicate a failure before the function call. 0310 * @stable ICU 4.0 0311 */ 0312 void applyPattern(const UnicodeString& pattern, UErrorCode& status); 0313 0314 0315 using Format::format; 0316 0317 /** 0318 * Formats a plural message for a given number. 0319 * 0320 * @param number a number for which the plural message should be formatted 0321 * for. If no pattern has been applied to this 0322 * <code>PluralFormat</code> object yet, the formatted number 0323 * will be returned. 0324 * @param status output param set to success/failure code on exit, which 0325 * must not indicate a failure before the function call. 0326 * @return the string containing the formatted plural message. 0327 * @stable ICU 4.0 0328 */ 0329 UnicodeString format(int32_t number, UErrorCode& status) const; 0330 0331 /** 0332 * Formats a plural message for a given number. 0333 * 0334 * @param number a number for which the plural message should be formatted 0335 * for. If no pattern has been applied to this 0336 * PluralFormat object yet, the formatted number 0337 * will be returned. 0338 * @param status output param set to success or failure code on exit, which 0339 * must not indicate a failure before the function call. 0340 * @return the string containing the formatted plural message. 0341 * @stable ICU 4.0 0342 */ 0343 UnicodeString format(double number, UErrorCode& status) const; 0344 0345 /** 0346 * Formats a plural message for a given number. 0347 * 0348 * @param number a number for which the plural message should be formatted 0349 * for. If no pattern has been applied to this 0350 * <code>PluralFormat</code> object yet, the formatted number 0351 * will be returned. 0352 * @param appendTo output parameter to receive result. 0353 * result is appended to existing contents. 0354 * @param pos On input: an alignment field, if desired. 0355 * On output: the offsets of the alignment field. 0356 * @param status output param set to success/failure code on exit, which 0357 * must not indicate a failure before the function call. 0358 * @return the string containing the formatted plural message. 0359 * @stable ICU 4.0 0360 */ 0361 UnicodeString& format(int32_t number, 0362 UnicodeString& appendTo, 0363 FieldPosition& pos, 0364 UErrorCode& status) const; 0365 0366 /** 0367 * Formats a plural message for a given number. 0368 * 0369 * @param number a number for which the plural message should be formatted 0370 * for. If no pattern has been applied to this 0371 * PluralFormat object yet, the formatted number 0372 * will be returned. 0373 * @param appendTo output parameter to receive result. 0374 * result is appended to existing contents. 0375 * @param pos On input: an alignment field, if desired. 0376 * On output: the offsets of the alignment field. 0377 * @param status output param set to success/failure code on exit, which 0378 * must not indicate a failure before the function call. 0379 * @return the string containing the formatted plural message. 0380 * @stable ICU 4.0 0381 */ 0382 UnicodeString& format(double number, 0383 UnicodeString& appendTo, 0384 FieldPosition& pos, 0385 UErrorCode& status) const; 0386 0387 #ifndef U_HIDE_DEPRECATED_API 0388 /** 0389 * Sets the locale used by this <code>PluraFormat</code> object. 0390 * Note: Calling this method resets this <code>PluraFormat</code> object, 0391 * i.e., a pattern that was applied previously will be removed, 0392 * and the NumberFormat is set to the default number format for 0393 * the locale. The resulting format behaves the same as one 0394 * constructed from {@link #PluralFormat(const Locale& locale, UPluralType type, UErrorCode& status)} 0395 * with UPLURAL_TYPE_CARDINAL. 0396 * @param locale the <code>locale</code> to use to configure the formatter. 0397 * @param status output param set to success/failure code on exit, which 0398 * must not indicate a failure before the function call. 0399 * @deprecated ICU 50 This method clears the pattern and might create 0400 * a different kind of PluralRules instance; 0401 * use one of the constructors to create a new instance instead. 0402 */ 0403 void setLocale(const Locale& locale, UErrorCode& status); 0404 #endif /* U_HIDE_DEPRECATED_API */ 0405 0406 /** 0407 * Sets the number format used by this formatter. You only need to 0408 * call this if you want a different number format than the default 0409 * formatter for the locale. 0410 * @param format the number format to use. 0411 * @param status output param set to success/failure code on exit, which 0412 * must not indicate a failure before the function call. 0413 * @stable ICU 4.0 0414 */ 0415 void setNumberFormat(const NumberFormat* format, UErrorCode& status); 0416 0417 /** 0418 * Assignment operator 0419 * 0420 * @param other the PluralFormat object to copy from. 0421 * @stable ICU 4.0 0422 */ 0423 PluralFormat& operator=(const PluralFormat& other); 0424 0425 /** 0426 * Return true if another object is semantically equal to this one. 0427 * 0428 * @param other the PluralFormat object to be compared with. 0429 * @return true if other is semantically equal to this. 0430 * @stable ICU 4.0 0431 */ 0432 virtual bool operator==(const Format& other) const override; 0433 0434 /** 0435 * Return true if another object is semantically unequal to this one. 0436 * 0437 * @param other the PluralFormat object to be compared with. 0438 * @return true if other is semantically unequal to this. 0439 * @stable ICU 4.0 0440 */ 0441 virtual bool operator!=(const Format& other) const; 0442 0443 /** 0444 * Clones this Format object polymorphically. The caller owns the 0445 * result and should delete it when done. 0446 * @stable ICU 4.0 0447 */ 0448 virtual PluralFormat* clone() const override; 0449 0450 /** 0451 * Formats a plural message for a number taken from a Formattable object. 0452 * 0453 * @param obj The object containing a number for which the 0454 * plural message should be formatted. 0455 * The object must be of a numeric type. 0456 * @param appendTo output parameter to receive result. 0457 * Result is appended to existing contents. 0458 * @param pos On input: an alignment field, if desired. 0459 * On output: the offsets of the alignment field. 0460 * @param status output param filled with success/failure status. 0461 * @return Reference to 'appendTo' parameter. 0462 * @stable ICU 4.0 0463 */ 0464 UnicodeString& format(const Formattable& obj, 0465 UnicodeString& appendTo, 0466 FieldPosition& pos, 0467 UErrorCode& status) const override; 0468 0469 /** 0470 * Returns the pattern from applyPattern() or constructor(). 0471 * 0472 * @param appendTo output parameter to receive result. 0473 * Result is appended to existing contents. 0474 * @return the UnicodeString with inserted pattern. 0475 * @stable ICU 4.0 0476 */ 0477 UnicodeString& toPattern(UnicodeString& appendTo); 0478 0479 /** 0480 * This method is not yet supported by <code>PluralFormat</code>. 0481 * <P> 0482 * Before calling, set parse_pos.index to the offset you want to start 0483 * parsing at in the source. After calling, parse_pos.index is the end of 0484 * the text you parsed. If error occurs, index is unchanged. 0485 * <P> 0486 * When parsing, leading whitespace is discarded (with a successful parse), 0487 * while trailing whitespace is left as is. 0488 * <P> 0489 * See Format::parseObject() for more. 0490 * 0491 * @param source The string to be parsed into an object. 0492 * @param result Formattable to be set to the parse result. 0493 * If parse fails, return contents are undefined. 0494 * @param parse_pos The position to start parsing at. Upon return 0495 * this param is set to the position after the 0496 * last character successfully parsed. If the 0497 * source is not parsed successfully, this param 0498 * will remain unchanged. 0499 * @stable ICU 4.0 0500 */ 0501 virtual void parseObject(const UnicodeString& source, 0502 Formattable& result, 0503 ParsePosition& parse_pos) const override; 0504 0505 /** 0506 * ICU "poor man's RTTI", returns a UClassID for this class. 0507 * 0508 * @stable ICU 4.0 0509 * 0510 */ 0511 static UClassID U_EXPORT2 getStaticClassID(); 0512 0513 /** 0514 * ICU "poor man's RTTI", returns a UClassID for the actual class. 0515 * 0516 * @stable ICU 4.0 0517 */ 0518 virtual UClassID getDynamicClassID() const override; 0519 0520 private: 0521 /** 0522 * @internal (private) 0523 */ 0524 class U_I18N_API PluralSelector : public UMemory { 0525 public: 0526 virtual ~PluralSelector(); 0527 /** 0528 * Given a number, returns the appropriate PluralFormat keyword. 0529 * 0530 * @param context worker object for the selector. 0531 * @param number The number to be plural-formatted. 0532 * @param ec Error code. 0533 * @return The selected PluralFormat keyword. 0534 * @internal (private) 0535 */ 0536 virtual UnicodeString select(void *context, double number, UErrorCode& ec) const = 0; 0537 }; 0538 0539 class U_I18N_API PluralSelectorAdapter : public PluralSelector { 0540 public: 0541 PluralSelectorAdapter() : pluralRules(nullptr) { 0542 } 0543 0544 virtual ~PluralSelectorAdapter(); 0545 0546 virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const override; 0547 0548 void reset(); 0549 0550 PluralRules* pluralRules; 0551 }; 0552 0553 Locale locale; 0554 MessagePattern msgPattern; 0555 NumberFormat* numberFormat; 0556 double offset; 0557 PluralSelectorAdapter pluralRulesWrapper; 0558 0559 PluralFormat() = delete; // default constructor not implemented 0560 void init(const PluralRules* rules, UPluralType type, UErrorCode& status); 0561 /** 0562 * Copies dynamically allocated values (pointer fields). 0563 * Others are copied using their copy constructors and assignment operators. 0564 */ 0565 void copyObjects(const PluralFormat& other); 0566 0567 UnicodeString& format(const Formattable& numberObject, double number, 0568 UnicodeString& appendTo, 0569 FieldPosition& pos, 0570 UErrorCode& status) const; 0571 0572 /** 0573 * Finds the PluralFormat sub-message for the given number, or the "other" sub-message. 0574 * @param pattern A MessagePattern. 0575 * @param partIndex the index of the first PluralFormat argument style part. 0576 * @param selector the PluralSelector for mapping the number (minus offset) to a keyword. 0577 * @param context worker object for the selector. 0578 * @param number a number to be matched to one of the PluralFormat argument's explicit values, 0579 * or mapped via the PluralSelector. 0580 * @param ec ICU error code. 0581 * @return the sub-message start part index. 0582 */ 0583 static int32_t findSubMessage( 0584 const MessagePattern& pattern, int32_t partIndex, 0585 const PluralSelector& selector, void *context, double number, UErrorCode& ec); 0586 0587 void parseType(const UnicodeString& source, const NFRule *rbnfLenientScanner, 0588 Formattable& result, FieldPosition& pos) const; 0589 0590 friend class MessageFormat; 0591 friend class NFRule; 0592 }; 0593 0594 U_NAMESPACE_END 0595 0596 #endif /* #if !UCONFIG_NO_FORMATTING */ 0597 0598 #endif /* U_SHOW_CPLUSPLUS_API */ 0599 0600 #endif // _PLURFMT 0601 //eof
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|