"Fossies" - the Fresh Open Source Software Archive

Member "icu/source/i18n/measunit_impl.h" (22 Apr 2020, 7024 Bytes) of package /linux/misc/icu4c-67_1-src.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "measunit_impl.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 67rc_vs_67_1.

    1 // © 2020 and later: Unicode, Inc. and others.
    2 // License & terms of use: http://www.unicode.org/copyright.html
    3 
    4 #ifndef __MEASUNIT_IMPL_H__
    5 #define __MEASUNIT_IMPL_H__
    6 
    7 #include "unicode/utypes.h"
    8 
    9 #if !UCONFIG_NO_FORMATTING
   10 
   11 #include "unicode/measunit.h"
   12 #include "cmemory.h"
   13 #include "charstr.h"
   14 
   15 U_NAMESPACE_BEGIN
   16 
   17 
   18 static const char16_t kDefaultCurrency[] = u"XXX";
   19 static const char kDefaultCurrency8[] = "XXX";
   20 
   21 
   22 /**
   23  * A struct representing a single unit (optional SI prefix and dimensionality).
   24  */
   25 struct SingleUnitImpl : public UMemory {
   26     /**
   27      * Gets a single unit from the MeasureUnit. If there are multiple single units, sets an error
   28      * code and returns the base dimensionless unit. Parses if necessary.
   29      */
   30     static SingleUnitImpl forMeasureUnit(const MeasureUnit& measureUnit, UErrorCode& status);
   31 
   32     /** Transform this SingleUnitImpl into a MeasureUnit, simplifying if possible. */
   33     MeasureUnit build(UErrorCode& status) const;
   34 
   35     /**
   36      * Compare this SingleUnitImpl to another SingleUnitImpl for the sake of
   37      * sorting and coalescing.
   38      *
   39      * Takes the sign of dimensionality into account, but not the absolute
   40      * value: per-meter is not considered the same as meter, but meter is
   41      * considered the same as square-meter.
   42      *
   43      * The dimensionless unit generally does not get compared, but if it did, it
   44      * would sort before other units by virtue of index being < 0 and
   45      * dimensionality not being negative.
   46      */
   47     int32_t compareTo(const SingleUnitImpl& other) const {
   48         if (dimensionality < 0 && other.dimensionality > 0) {
   49             // Positive dimensions first
   50             return 1;
   51         }
   52         if (dimensionality > 0 && other.dimensionality < 0) {
   53             return -1;
   54         }
   55         if (index < other.index) {
   56             return -1;
   57         }
   58         if (index > other.index) {
   59             return 1;
   60         }
   61         if (siPrefix < other.siPrefix) {
   62             return -1;
   63         }
   64         if (siPrefix > other.siPrefix) {
   65             return 1;
   66         }
   67         return 0;
   68     }
   69 
   70     /**
   71      * Return whether this SingleUnitImpl is compatible with another for the purpose of coalescing.
   72      *
   73      * Units with the same base unit and SI prefix should match, except that they must also have
   74      * the same dimensionality sign, such that we don't merge numerator and denominator.
   75      */
   76     bool isCompatibleWith(const SingleUnitImpl& other) const {
   77         return (compareTo(other) == 0);
   78     }
   79 
   80     /**
   81      * Returns true if this unit is the "dimensionless base unit", as produced
   82      * by the MeasureUnit() default constructor. (This does not include the
   83      * likes of concentrations or angles.)
   84      */
   85     bool isDimensionless() const {
   86         return index == -1;
   87     }
   88 
   89     /**
   90      * Simple unit index, unique for every simple unit, -1 for the dimensionless
   91      * unit. This is an index into a string list in measunit_extra.cpp.
   92      *
   93      * The default value is -1, meaning the dimensionless unit:
   94      * isDimensionless() will return true, until index is changed.
   95      */
   96     int32_t index = -1;
   97 
   98     /**
   99      * SI prefix.
  100      *
  101      * This is ignored for the dimensionless unit.
  102      */
  103     UMeasureSIPrefix siPrefix = UMEASURE_SI_PREFIX_ONE;
  104 
  105     /**
  106      * Dimensionality.
  107      *
  108      * This is meaningless for the dimensionless unit.
  109      */
  110     int32_t dimensionality = 1;
  111 };
  112 
  113 
  114 /**
  115  * Internal representation of measurement units. Capable of representing all complexities of units,
  116  * including mixed and compound units.
  117  */
  118 struct MeasureUnitImpl : public UMemory {
  119     /** Extract the MeasureUnitImpl from a MeasureUnit. */
  120     static inline const MeasureUnitImpl* get(const MeasureUnit& measureUnit) {
  121         return measureUnit.fImpl;
  122     }
  123 
  124     /**
  125      * Parse a unit identifier into a MeasureUnitImpl.
  126      *
  127      * @param identifier The unit identifier string.
  128      * @param status Set if the identifier string is not valid.
  129      * @return A newly parsed value object. Behaviour of this unit is
  130      * unspecified if an error is returned via status.
  131      */
  132     static MeasureUnitImpl forIdentifier(StringPiece identifier, UErrorCode& status);
  133 
  134     /**
  135      * Extract the MeasureUnitImpl from a MeasureUnit, or parse if it is not present.
  136      * 
  137      * @param measureUnit The source MeasureUnit.
  138      * @param memory A place to write the new MeasureUnitImpl if parsing is required.
  139      * @param status Set if an error occurs.
  140      * @return A reference to either measureUnit.fImpl or memory.
  141      */
  142     static const MeasureUnitImpl& forMeasureUnit(
  143         const MeasureUnit& measureUnit, MeasureUnitImpl& memory, UErrorCode& status);
  144 
  145     /**
  146      * Extract the MeasureUnitImpl from a MeasureUnit, or parse if it is not present.
  147      *
  148      * @param measureUnit The source MeasureUnit.
  149      * @param status Set if an error occurs.
  150      * @return A value object, either newly parsed or copied from measureUnit.
  151      */
  152     static MeasureUnitImpl forMeasureUnitMaybeCopy(
  153         const MeasureUnit& measureUnit, UErrorCode& status);
  154 
  155     /**
  156      * Used for currency units.
  157      */
  158     static inline MeasureUnitImpl forCurrencyCode(StringPiece currencyCode) {
  159         MeasureUnitImpl result;
  160         UErrorCode localStatus = U_ZERO_ERROR;
  161         result.identifier.append(currencyCode, localStatus);
  162         // localStatus is not expected to fail since currencyCode should be 3 chars long
  163         return result;
  164     }
  165 
  166     /** Transform this MeasureUnitImpl into a MeasureUnit, simplifying if possible. */
  167     MeasureUnit build(UErrorCode& status) &&;
  168 
  169     /**
  170      * Create a copy of this MeasureUnitImpl. Don't use copy constructor to make this explicit.
  171      */
  172     inline MeasureUnitImpl copy(UErrorCode& status) const {
  173         MeasureUnitImpl result;
  174         result.complexity = complexity;
  175         result.units.appendAll(units, status);
  176         result.identifier.append(identifier, status);
  177         return result;
  178     }
  179 
  180     /** Mutates this MeasureUnitImpl to take the reciprocal. */
  181     void takeReciprocal(UErrorCode& status);
  182 
  183     /**
  184      * Mutates this MeasureUnitImpl to append a single unit.
  185      *
  186      * @return true if a new item was added. If unit is the dimensionless unit,
  187      * it is never added: the return value will always be false.
  188      */
  189     bool append(const SingleUnitImpl& singleUnit, UErrorCode& status);
  190 
  191     /** The complexity, either SINGLE, COMPOUND, or MIXED. */
  192     UMeasureUnitComplexity complexity = UMEASURE_UNIT_SINGLE;
  193 
  194     /**
  195      * The list of simple units. These may be summed or multiplied, based on the
  196      * value of the complexity field.
  197      *
  198      * The "dimensionless" unit (SingleUnitImpl default constructor) must not be
  199      * added to this list.
  200      */
  201     MaybeStackVector<SingleUnitImpl> units;
  202 
  203     /**
  204      * The full unit identifier.  Owned by the MeasureUnitImpl.  Empty if not computed.
  205      */
  206     CharString identifier;
  207 };
  208 
  209 
  210 U_NAMESPACE_END
  211 
  212 #endif /* #if !UCONFIG_NO_FORMATTING */
  213 #endif //__MEASUNIT_IMPL_H__