xref: /aosp_15_r20/external/icu/libicu/cts_headers/units_data.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
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 __UNITS_DATA_H__
8 #define __UNITS_DATA_H__
9 
10 #include <limits>
11 
12 #include "charstr.h"
13 #include "cmemory.h"
14 #include "unicode/stringpiece.h"
15 #include "unicode/uobject.h"
16 
17 U_NAMESPACE_BEGIN
18 namespace units {
19 
20 /**
21  * Encapsulates "convertUnits" information from units resources, specifying how
22  * to convert from one unit to another.
23  *
24  * Information in this class is still in the form of strings: symbolic constants
25  * need to be interpreted. Rationale: symbols can cancel out for higher
26  * precision conversion - going from feet to inches should cancel out the
27  * `ft_to_m` constant.
28  */
29 class U_I18N_API ConversionRateInfo : public UMemory {
30   public:
ConversionRateInfo()31     ConversionRateInfo() {}
ConversionRateInfo(StringPiece sourceUnit,StringPiece baseUnit,StringPiece factor,StringPiece offset,UErrorCode & status)32     ConversionRateInfo(StringPiece sourceUnit, StringPiece baseUnit, StringPiece factor,
33                        StringPiece offset, UErrorCode &status)
34         : sourceUnit(), baseUnit(), factor(), offset(), specialMappingName() {
35         this->sourceUnit.append(sourceUnit, status);
36         this->baseUnit.append(baseUnit, status);
37         this->factor.append(factor, status);
38         this->offset.append(offset, status);
39     }
40     CharString sourceUnit;
41     CharString baseUnit;
42     CharString factor;
43     CharString offset;
44     CharString specialMappingName; // the name of a special mapping used instead of factor + optional offset.
45     CharString systems;
46 };
47 
48 } // namespace units
49 
50 // Export explicit template instantiations of MaybeStackArray, MemoryPool and
51 // MaybeStackVector. This is required when building DLLs for Windows. (See
52 // datefmt.h, collationiterator.h, erarules.h and others for similar examples.)
53 //
54 // Note: These need to be outside of the units namespace, or Clang will generate
55 // a compile error.
56 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
57 template class U_I18N_API MaybeStackArray<units::ConversionRateInfo*, 8>;
58 template class U_I18N_API MemoryPool<units::ConversionRateInfo, 8>;
59 template class U_I18N_API MaybeStackVector<units::ConversionRateInfo, 8>;
60 #endif
61 
62 namespace units {
63 
64 /**
65  * Returns ConversionRateInfo for all supported conversions.
66  *
67  * @param result Receives the set of conversion rates.
68  * @param status Receives status.
69  */
70 void U_I18N_API getAllConversionRates(MaybeStackVector<ConversionRateInfo> &result, UErrorCode &status);
71 
72 /**
73  * Contains all the supported conversion rates.
74  */
75 class U_I18N_API ConversionRates {
76   public:
77     /**
78      * Constructor
79      *
80      * @param status Receives status.
81      */
ConversionRates(UErrorCode & status)82     ConversionRates(UErrorCode &status) { getAllConversionRates(conversionInfo_, status); }
83 
84     /**
85      * Returns a pointer to the conversion rate info that match the `source`.
86      *
87      * @param source Contains the source.
88      * @param status Receives status.
89      */
90     const ConversionRateInfo *extractConversionInfo(StringPiece source, UErrorCode &status) const;
91 
92   private:
93     MaybeStackVector<ConversionRateInfo> conversionInfo_;
94 };
95 
96 // Encapsulates unitPreferenceData information from units resources, specifying
97 // a sequence of output unit preferences.
98 struct U_I18N_API UnitPreference : public UMemory {
99     // Set geq to 1.0 by default
UnitPreferenceUnitPreference100     UnitPreference() : geq(1.0) {}
101     CharString unit;
102     double geq;
103     UnicodeString skeleton;
104 
UnitPreferenceUnitPreference105     UnitPreference(const UnitPreference &other) {
106         UErrorCode status = U_ZERO_ERROR;
107         this->unit.append(other.unit, status);
108         this->geq = other.geq;
109         this->skeleton = other.skeleton;
110     }
111 };
112 
113 /**
114  * Metadata about the preferences in UnitPreferences::unitPrefs_.
115  *
116  * This class owns all of its data.
117  *
118  * UnitPreferenceMetadata lives in the anonymous namespace, because it should
119  * only be useful to internal code and unit testing code.
120  */
121 class U_I18N_API UnitPreferenceMetadata : public UMemory {
122   public:
UnitPreferenceMetadata()123     UnitPreferenceMetadata() {}
124     // Constructor, makes copies of the parameters passed to it.
125     UnitPreferenceMetadata(StringPiece category, StringPiece usage, StringPiece region,
126                            int32_t prefsOffset, int32_t prefsCount, UErrorCode &status);
127 
128     // Unit category (e.g. "length", "mass", "electric-capacitance").
129     CharString category;
130     // Usage (e.g. "road", "vehicle-fuel", "blood-glucose"). Every category
131     // should have an entry for "default" usage. TODO(hugovdm): add a test for
132     // this.
133     CharString usage;
134     // Region code (e.g. "US", "CZ", "001"). Every usage should have an entry
135     // for the "001" region ("world"). TODO(hugovdm): add a test for this.
136     CharString region;
137     // Offset into the UnitPreferences::unitPrefs_ list where the relevant
138     // preferences are found.
139     int32_t prefsOffset;
140     // The number of preferences that form this set.
141     int32_t prefsCount;
142 
143     int32_t compareTo(const UnitPreferenceMetadata &other) const;
144     int32_t compareTo(const UnitPreferenceMetadata &other, bool *foundCategory, bool *foundUsage,
145                       bool *foundRegion) const;
146 };
147 
148 } // namespace units
149 
150 // Export explicit template instantiations of MaybeStackArray, MemoryPool and
151 // MaybeStackVector. This is required when building DLLs for Windows. (See
152 // datefmt.h, collationiterator.h, erarules.h and others for similar examples.)
153 //
154 // Note: These need to be outside of the units namespace, or Clang will generate
155 // a compile error.
156 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
157 template class U_I18N_API MaybeStackArray<units::UnitPreferenceMetadata*, 8>;
158 template class U_I18N_API MemoryPool<units::UnitPreferenceMetadata, 8>;
159 template class U_I18N_API MaybeStackVector<units::UnitPreferenceMetadata, 8>;
160 template class U_I18N_API MaybeStackArray<units::UnitPreference*, 8>;
161 template class U_I18N_API MemoryPool<units::UnitPreference, 8>;
162 template class U_I18N_API MaybeStackVector<units::UnitPreference, 8>;
163 #endif
164 
165 namespace units {
166 
167 /**
168  * Unit Preferences information for various locales and usages.
169  */
170 class U_I18N_API UnitPreferences {
171   public:
172     /**
173      * Constructor, loads all the preference data.
174      *
175      * @param status Receives status.
176      */
177     UnitPreferences(UErrorCode &status);
178 
179     /**
180      * Returns the set of unit preferences in the particular category that best
181      * matches the specified usage and region.
182      *
183      * If region can't be found, falls back to global (001). If usage can't be
184      * found, falls back to "default".
185      *
186      * @param category The category within which to look up usage and region.
187      * (TODO(hugovdm): improve docs on how to find the category, once the lookup
188      * function is added.)
189      * @param usage The usage parameter. (TODO(hugovdm): improve this
190      * documentation. Add reference to some list of usages we support.) If the
191      * given usage is not found, the method automatically falls back to
192      * "default".
193      * @param region The region whose preferences are desired. If there are no
194      * specific preferences for the requested region, the method automatically
195      * falls back to region "001" ("world").
196      * @param outPreferences A pointer into an array of preferences: essentially
197      * an array slice in combination with preferenceCount.
198      * @param preferenceCount The number of unit preferences that belong to the
199      * result set.
200      * @param status Receives status.
201      */
202     MaybeStackVector<UnitPreference> getPreferencesFor(StringPiece category, StringPiece usage,
203                                                        const Locale &locale,
204 
205                                                        UErrorCode &status) const;
206 
207   protected:
208     // Metadata about the sets of preferences, this is the index for looking up
209     // preferences in the unitPrefs_ list.
210     MaybeStackVector<UnitPreferenceMetadata> metadata_;
211     // All the preferences as a flat list: which usage and region preferences
212     // are associated with is stored in `metadata_`.
213     MaybeStackVector<UnitPreference> unitPrefs_;
214 };
215 
216 } // namespace units
217 U_NAMESPACE_END
218 
219 #endif //__UNITS_DATA_H__
220 
221 #endif /* #if !UCONFIG_NO_FORMATTING */
222