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_COMPLEXCONVERTER_H__ 8 #define __UNITS_COMPLEXCONVERTER_H__ 9 10 #include "cmemory.h" 11 #include "measunit_impl.h" 12 #include "number_roundingutils.h" 13 #include "unicode/errorcode.h" 14 #include "unicode/measure.h" 15 #include "units_converter.h" 16 #include "units_data.h" 17 18 U_NAMESPACE_BEGIN 19 20 // Export explicit template instantiations of MaybeStackArray, MemoryPool and 21 // MaybeStackVector. This is required when building DLLs for Windows. (See 22 // datefmt.h, collationiterator.h, erarules.h and others for similar examples.) 23 // 24 // Note: These need to be outside of the units namespace, or Clang will generate 25 // a compile error. 26 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 27 template class U_I18N_API MaybeStackArray<units::UnitConverter*, 8>; 28 template class U_I18N_API MemoryPool<units::UnitConverter, 8>; 29 template class U_I18N_API MaybeStackVector<units::UnitConverter, 8>; 30 template class U_I18N_API MaybeStackArray<MeasureUnitImpl*, 8>; 31 template class U_I18N_API MemoryPool<MeasureUnitImpl, 8>; 32 template class U_I18N_API MaybeStackVector<MeasureUnitImpl, 8>; 33 template class U_I18N_API MaybeStackArray<MeasureUnit*, 8>; 34 template class U_I18N_API MemoryPool<MeasureUnit, 8>; 35 template class U_I18N_API MaybeStackVector<MeasureUnit, 8>; 36 #endif 37 38 namespace units { 39 40 /** 41 * Converts from single or compound unit to single, compound or mixed units. 42 * For example, from `meter` to `foot+inch`. 43 * 44 * DESIGN: 45 * This class uses `UnitConverter` in order to perform the single converter (i.e. converters from a 46 * single unit to another single unit). Therefore, `ComplexUnitsConverter` class contains multiple 47 * instances of the `UnitConverter` to perform the conversion. 48 */ 49 class U_I18N_API ComplexUnitsConverter : public UMemory { 50 public: 51 /** 52 * Constructor of `ComplexUnitsConverter`. 53 * NOTE: 54 * - inputUnit and outputUnits must be under the same category 55 * - e.g. meter to feet and inches --> all of them are length units. 56 * 57 * @param inputUnit represents the source unit. (should be single or compound unit). 58 * @param outputUnits represents the output unit. could be any type. (single, compound or mixed). 59 * @param status 60 */ 61 ComplexUnitsConverter(const MeasureUnitImpl &inputUnit, const MeasureUnitImpl &outputUnits, 62 const ConversionRates &ratesInfo, UErrorCode &status); 63 64 // Returns true if the specified `quantity` of the `inputUnit`, expressed in terms of the biggest 65 // unit in the MeasureUnit `outputUnit`, is greater than or equal to `limit`. 66 // For example, if the input unit is `meter` and the target unit is `foot+inch`. Therefore, this 67 // function will convert the `quantity` from `meter` to `foot`, then, it will compare the value in 68 // `foot` with the `limit`. 69 UBool greaterThanOrEqual(double quantity, double limit) const; 70 71 // Returns outputMeasures which is an array with the corresponding values. 72 // - E.g. converting meters to feet and inches. 73 // 1 meter --> 3 feet, 3.3701 inches 74 // NOTE: 75 // the smallest element is the only element that could have fractional values. And all 76 // other elements are floored to the nearest integer 77 MaybeStackVector<Measure> 78 convert(double quantity, icu::number::impl::RoundingImpl *rounder, UErrorCode &status) const; 79 80 private: 81 MaybeStackVector<UnitConverter> unitConverters_; 82 // Individual units of mixed units, sorted big to small 83 MaybeStackVector<MeasureUnitImpl> units_; 84 // Individual units of mixed units, sorted in desired output order 85 MaybeStackVector<MeasureUnit> outputUnits_; 86 }; 87 88 } // namespace units 89 U_NAMESPACE_END 90 91 #endif //__UNITS_COMPLEXCONVERTER_H__ 92 93 #endif /* #if !UCONFIG_NO_FORMATTING */ 94