]> granicus.if.org Git - icu/commitdiff
add the internal design documentation
authorYounies Mahmoud <younies.mahmoud@gmail.com>
Tue, 9 Jun 2020 12:56:28 +0000 (14:56 +0200)
committerYounies Mahmoud <younies.mahmoud@gmail.com>
Tue, 9 Jun 2020 12:56:28 +0000 (14:56 +0200)
icu4c/source/i18n/complexunitsconverter.h
icu4c/source/i18n/unitconverter.h
icu4c/source/i18n/unitsrouter.h

index 3b71689416f0b851ed0fb5354f8446d3d0ae3846..1034571b0671989c60260fb9bfd15e2a12ebf681 100644 (file)
 
 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:
     /**
@@ -38,6 +47,9 @@ class U_I18N_API ComplexUnitsConverter {
 
     // 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.
index fe664f21e504142ecface469fe5f8d758ec0ef4c..61ed7f4e688541b3e1d510636a8395cb5bf751d4 100644 (file)
@@ -44,6 +44,10 @@ UnitsConvertibilityState U_I18N_API checkConvertibility(const MeasureUnit &sourc
 
 /**
  * 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:
@@ -57,8 +61,8 @@ class U_I18N_API UnitConverter : public UMemory {
      * @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.
index 9e38f150569b2f326c9610565e57e2e97b0cadcd..1b29d9d8f3a3a79ebb78f3cb1123cd3b08d9143a 100644 (file)
@@ -7,6 +7,8 @@
 #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;
@@ -25,8 +36,41 @@ struct ConverterPreference : UMemory {
     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);