U_NAMESPACE_BEGIN
+/**
+ * Convert from single unit to multiple/complex unit. For example, from `meter` to `foot+inch`.
+ *
+ *
+ * DESIGN:
+ * This class uses `UnitConverter` in order to perform the single converter (i.e. converters from a
+ * single unit to another single unit). Therefore, `ComplexUnitsConverter` class contains multiple
+ * instances of the `UnitConverter` to perform the conversion.
+ */
class U_I18N_API ComplexUnitsConverter {
public:
/**
// Returns true if the `quantity` in the `inputUnit` is greater than or equal than the `limit` in the
// biggest `outputUnits`
+ // For example, if the input unit is `meter` and the target unit is `foot+inch`. Therefore, this
+ // function will convert the `quantity` from `meter` to `foot`, then, it will compare the value in
+ // `foot` with the `limit`.
UBool greaterThanOrEqual(double quantity, double limit) const;
// Returns outputMeasures which is an array with the correspinding values.
/**
* Converts from a source `MeasureUnit` to a target `MeasureUnit`.
+ *
+ * NOTE:
+ * the source and the target must be singular such as `meter` to `mile` or `mile-per-second` to
+ * `kilometer-per-millisecond`. However, `foot+inch` is not permitted.
*/
class U_I18N_API UnitConverter : public UMemory {
public:
* @param target represents the target unit.
* @param status
*/
- UnitConverter(MeasureUnit source, MeasureUnit target,
- const ConversionRates &ratesInfo, UErrorCode &status);
+ UnitConverter(MeasureUnit source, MeasureUnit target, const ConversionRates &ratesInfo,
+ UErrorCode &status);
/**
* Convert a value in the source unit to another value in the target unit.
#ifndef __UNITSROUTER_H__
#define __UNITSROUTER_H__
+#include <limits>
+
#include "charstr.h" // CharString
#include "cmemory.h"
#include "complexunitsconverter.h"
U_NAMESPACE_BEGIN
+/**
+ * Contains the complex unit converter and the limit which representing the smallest value that the
+ * converter should accept. For example, if the converter is converting to `foot+inch` and the limit
+ * equals 3.0, thus means the converter should not convert to a value less than `3.0 feet`.
+ *
+ * NOTE:
+ * if the limit doest not has a value `i.e. (std::numeric_limits<double>::lowest())`, this mean there
+ * is no limit for the converter.
+ */
struct ConverterPreference : UMemory {
ComplexUnitsConverter converter;
double limit;
ConverterPreference(MeasureUnit source, MeasureUnit complexTarget, double limit,
const ConversionRates &ratesInfo, UErrorCode &status)
: converter(source, complexTarget, ratesInfo, status), limit(limit) {}
+
+ ConverterPreference(MeasureUnit source, MeasureUnit complexTarget, const ConversionRates &ratesInfo,
+ UErrorCode &status)
+ : ConverterPreference(source, complexTarget, std::numeric_limits<double>::lowest(), ratesInfo,
+ status) {}
};
+/**
+ * `UnitsRouter` responsible for converting from a single unit (such as `meter` or `meter-per-second`) to
+ * one of the complex units based on the limits.
+ * For example:
+ * if the input is `meter` and the output as following
+ * {`foot+inch`, limit: 3.0}
+ * {`inch` , limit: no value (-inf)}
+ * Thus means if the input in `meter` is greater than or equal to `3.0 feet`, the output will be in
+ * `foot+inch`, otherwise, the output will be in `inch`.
+ *
+ * NOTE:
+ * the output units and the their limits MUST BE in order, for example, if the output units, from the
+ * previous example, are the following:
+ * {`inch` , limit: no value (-inf)}
+ * {`foot+inch`, limit: 3.0}
+ * IN THIS CASE THE OUTPUT WILL BE ALWAYS IN `inch`.
+ *
+ * NOTE:
+ * the output units and their limits will be extracted from the units preferences database by knowing
+ * the followings:
+ * - input unit
+ * - locale
+ * - usage
+ *
+ * DESIGN:
+ * `UnitRouter` uses internally `ComplexUnitConverter` in order to convert the input units to the
+ * desired complex units and to check the limit too.
+ */
class U_I18N_API UnitsRouter {
public:
UnitsRouter(MeasureUnit inputUnit, StringPiece locale, StringPiece usage, UErrorCode &status);