1 // © 2020 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/utypes.h"
5 
6 #if !UCONFIG_NO_FORMATTING
7 #ifndef __NUMBER_USAGEPREFS_H__
8 #define __NUMBER_USAGEPREFS_H__
9 
10 #include "cmemory.h"
11 #include "number_types.h"
12 #include "unicode/listformatter.h"
13 #include "unicode/localpointer.h"
14 #include "unicode/locid.h"
15 #include "unicode/measunit.h"
16 #include "unicode/stringpiece.h"
17 #include "unicode/uobject.h"
18 #include "units_converter.h"
19 #include "units_router.h"
20 
21 U_NAMESPACE_BEGIN
22 
23 using ::icu::units::ComplexUnitsConverter;
24 using ::icu::units::UnitsRouter;
25 
26 namespace number {
27 namespace impl {
28 
29 /**
30  * A MicroPropsGenerator which uses UnitsRouter to produce output converted to a
31  * MeasureUnit appropriate for a particular localized usage: see
32  * NumberFormatterSettings::usage().
33  */
34 class U_I18N_API UsagePrefsHandler : public MicroPropsGenerator, public UMemory {
35   public:
36     UsagePrefsHandler(const Locale &locale, const MeasureUnit &inputUnit, const StringPiece usage,
37                       const MicroPropsGenerator *parent, UErrorCode &status);
38 
39     /**
40      * Obtains the appropriate output value, MeasureUnit and
41      * rounding/precision behaviour from the UnitsRouter.
42      *
43      * The output unit is passed on to the LongNameHandler via
44      * micros.outputUnit.
45      */
46     void processQuantity(DecimalQuantity &quantity, MicroProps &micros,
47                          UErrorCode &status) const U_OVERRIDE;
48 
49     /**
50      * Returns the list of possible output units, i.e. the full set of
51      * preferences, for the localized, usage-specific unit preferences.
52      *
53      * The returned pointer should be valid for the lifetime of the
54      * UsagePrefsHandler instance.
55      */
getOutputUnits()56     const MaybeStackVector<MeasureUnit> *getOutputUnits() const {
57         return fUnitsRouter.getOutputUnits();
58     }
59 
60   private:
61     UnitsRouter fUnitsRouter;
62     const MicroPropsGenerator *fParent;
63 };
64 
65 } // namespace impl
66 } // namespace number
67 
68 // Export explicit template instantiations of LocalPointerBase and LocalPointer.
69 // This is required when building DLLs for Windows. (See datefmt.h,
70 // collationiterator.h, erarules.h and others for similar examples.)
71 //
72 // Note: These need to be outside of the number::impl namespace, or Clang will
73 // generate a compile error.
74 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
75 #if defined(_MSC_VER)
76 // Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
77 #pragma warning(push)
78 #pragma warning(disable: 4661)
79 #endif
80 template class U_I18N_API LocalPointerBase<ComplexUnitsConverter>;
81 template class U_I18N_API LocalPointer<ComplexUnitsConverter>;
82 #if defined(_MSC_VER)
83 #pragma warning(pop)
84 #endif
85 #endif
86 
87 namespace number {
88 namespace impl {
89 
90 /**
91  * A MicroPropsGenerator which converts a measurement from one MeasureUnit to
92  * another. In particular, the output MeasureUnit may be a mixed unit. (The
93  * input unit may not be a mixed unit.)
94  */
95 class U_I18N_API UnitConversionHandler : public MicroPropsGenerator, public UMemory {
96   public:
97     /**
98      * Constructor.
99      *
100      * @param targetUnit Specifies the output MeasureUnit. The input MeasureUnit
101      *     is derived from it: in case of a mixed unit, the biggest unit is
102      *     taken as the input unit. If not a mixed unit, the input unit will be
103      *     the same as the output unit and no unit conversion takes place.
104      * @param parent The parent MicroPropsGenerator.
105      * @param status Receives status.
106      */
107     UnitConversionHandler(const MeasureUnit &targetUnit, const MicroPropsGenerator *parent,
108                           UErrorCode &status);
109 
110     /**
111      * Obtains the appropriate output values from the Unit Converter.
112      */
113     void processQuantity(DecimalQuantity &quantity, MicroProps &micros,
114                          UErrorCode &status) const U_OVERRIDE;
115   private:
116     MeasureUnit fOutputUnit;
117     LocalPointer<ComplexUnitsConverter> fUnitConverter;
118     const MicroPropsGenerator *fParent;
119 };
120 
121 } // namespace impl
122 } // namespace number
123 U_NAMESPACE_END
124 
125 #endif // __NUMBER_USAGEPREFS_H__
126 #endif /* #if !UCONFIG_NO_FORMATTING */
127