1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 ******************************************************************************
5 * Copyright (C) 2014-2016, International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 ******************************************************************************
8 * quantityformatter.h
9 */
10 
11 #ifndef __QUANTITY_FORMATTER_H__
12 #define __QUANTITY_FORMATTER_H__
13 
14 #include "unicode/utypes.h"
15 #include "unicode/uobject.h"
16 
17 #if !UCONFIG_NO_FORMATTING
18 
19 #include "standardplural.h"
20 
21 U_NAMESPACE_BEGIN
22 
23 class SimpleFormatter;
24 class UnicodeString;
25 class PluralRules;
26 class NumberFormat;
27 class Formattable;
28 class FieldPosition;
29 class FormattedStringBuilder;
30 
31 /**
32  * A plural aware formatter that is good for expressing a single quantity and
33  * a unit.
34  * <p>
35  * First use the add() methods to add a pattern for each plural variant.
36  * There must be a pattern for the "other" variant.
37  * Then use the format() method.
38  * <p>
39  * Concurrent calls only to const methods on a QuantityFormatter object are
40  * safe, but concurrent const and non-const method calls on a QuantityFormatter
41  * object are not safe and require synchronization.
42  *
43  */
44 class U_I18N_API QuantityFormatter : public UMemory {
45 public:
46     /**
47      * Default constructor.
48      */
49     QuantityFormatter();
50 
51     /**
52      * Copy constructor.
53      */
54     QuantityFormatter(const QuantityFormatter& other);
55 
56     /**
57      * Assignment operator
58      */
59     QuantityFormatter &operator=(const QuantityFormatter& other);
60 
61     /**
62      * Destructor.
63      */
64     ~QuantityFormatter();
65 
66     /**
67      * Removes all variants from this object including the "other" variant.
68      */
69     void reset();
70 
71     /**
72      * Adds a plural variant if there is none yet for the plural form.
73      *
74      * @param variant "zero", "one", "two", "few", "many", "other"
75      * @param rawPattern the pattern for the variant e.g "{0} meters"
76      * @param status any error returned here.
77      * @return TRUE on success; FALSE if status was set to a non zero error.
78      */
79     UBool addIfAbsent(const char *variant, const UnicodeString &rawPattern, UErrorCode &status);
80 
81     /**
82      * returns TRUE if this object has at least the "other" variant.
83      */
84     UBool isValid() const;
85 
86     /**
87      * Gets the pattern formatter that would be used for a particular variant.
88      * If isValid() returns TRUE, this method is guaranteed to return a
89      * non-NULL value.
90      */
91     const SimpleFormatter *getByVariant(const char *variant) const;
92 
93     /**
94      * Formats a number with this object appending the result to appendTo.
95      * At least the "other" variant must be added to this object for this
96      * method to work.
97      *
98      * @param number the single number.
99      * @param fmt formats the number
100      * @param rules computes the plural variant to use.
101      * @param appendTo result appended here.
102      * @param status any error returned here.
103      * @return appendTo
104      */
105     UnicodeString &format(
106             const Formattable &number,
107             const NumberFormat &fmt,
108             const PluralRules &rules,
109             UnicodeString &appendTo,
110             FieldPosition &pos,
111             UErrorCode &status) const;
112 
113     /**
114      * Selects the standard plural form for the number/formatter/rules.
115      * TODO(13591): Remove this method.
116      */
117     static StandardPlural::Form selectPlural(
118             const Formattable &number,
119             const NumberFormat &fmt,
120             const PluralRules &rules,
121             UnicodeString &formattedNumber,
122             FieldPosition &pos,
123             UErrorCode &status);
124 
125     /**
126      * Formats a quantity and selects its plural form. The output is appended
127      * to a FormattedStringBuilder in order to retain field information.
128      *
129      * @param quantity The number to format.
130      * @param fmt The formatter to use to format the number.
131      * @param rules The rules to use to select the plural form of the
132      *              formatted number.
133      * @param output Where to append the result of the format operation.
134      * @param pluralForm Output variable populated with the plural form of the
135      *                   formatted number.
136      * @param status Set if an error occurs.
137      */
138     static void formatAndSelect(
139             double quantity,
140             const NumberFormat& fmt,
141             const PluralRules& rules,
142             FormattedStringBuilder& output,
143             StandardPlural::Form& pluralForm,
144             UErrorCode& status);
145 
146     /**
147      * Formats the pattern with the value and adjusts the FieldPosition.
148      * TODO: Remove?
149      */
150     static UnicodeString &format(
151             const SimpleFormatter &pattern,
152             const UnicodeString &value,
153             UnicodeString &appendTo,
154             FieldPosition &pos,
155             UErrorCode &status);
156 
157 private:
158     SimpleFormatter *formatters[StandardPlural::COUNT];
159 };
160 
161 U_NAMESPACE_END
162 
163 #endif
164 
165 #endif
166