tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MeasureUnit.h (4319B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef intl_components_MeasureUnit_h_
      6 #define intl_components_MeasureUnit_h_
      7 
      8 #include "mozilla/Assertions.h"
      9 #include "mozilla/intl/ICU4CGlue.h"
     10 #include "mozilla/intl/ICUError.h"
     11 #include "mozilla/Result.h"
     12 #include "mozilla/UniquePtr.h"
     13 
     14 #include <iterator>
     15 #include <stddef.h>
     16 #include <stdint.h>
     17 
     18 struct UResourceBundle;
     19 
     20 namespace mozilla::intl {
     21 
     22 /**
     23 * This component is a Mozilla-focused API for working with measurement units in
     24 * internationalization code. It is used in coordination with other operations
     25 * such as number formatting.
     26 */
     27 class MeasureUnit final {
     28  class UResourceBundleDeleter {
     29   public:
     30    void operator()(UResourceBundle* aPtr);
     31  };
     32 
     33  using UniqueUResourceBundle =
     34      UniquePtr<UResourceBundle, UResourceBundleDeleter>;
     35 
     36 public:
     37  MeasureUnit() = delete;
     38 
     39  class Enumeration final {
     40    // Resource bundle for the root locale.
     41    UniqueUResourceBundle mRootLocale = nullptr;
     42 
     43    // Resource bundle for the root locale's "units" resource table.
     44    UniqueUResourceBundle mUnits = nullptr;
     45 
     46    // The overall amount of available units.
     47    int32_t mUnitsSize = 0;
     48 
     49   public:
     50    Enumeration(UniqueUResourceBundle aRootLocale,
     51                UniqueUResourceBundle aUnits);
     52 
     53    class Iterator {
     54     public:
     55      // std::iterator traits.
     56      using iterator_category = std::input_iterator_tag;
     57      using value_type = SpanResult<char>;
     58      using difference_type = ptrdiff_t;
     59      using pointer = value_type*;
     60      using reference = value_type&;
     61 
     62     private:
     63      const Enumeration& mEnumeration;
     64 
     65      // Resource bundle to a measurement type within the "units" table.
     66      //
     67      // Measurement types describe various categories, like "area", "length",
     68      // or "mass".
     69      UniqueUResourceBundle mType = nullptr;
     70 
     71      // Resource bundle to a specific subtype within the type table.
     72      //
     73      // Measurement subtypes describe concrete measure units, like "acre",
     74      // "meter", or "kilogram".
     75      UniqueUResourceBundle mSubtype = nullptr;
     76 
     77      // The next position within the "units" table.
     78      int32_t mUnitsPos = 0;
     79 
     80      // The overall amount of types within the |mType| table.
     81      int32_t mTypeSize = 0;
     82 
     83      // The next position within the |mType| table.
     84      int32_t mTypePos = 0;
     85 
     86      // Flag set when an ICU error has occurred. All further operations on this
     87      // iterator will return an error result when this flag is set.
     88      bool mHasError = false;
     89 
     90      void advance();
     91 
     92     public:
     93      Iterator(const Enumeration& aEnumeration, int32_t aUnitsPos)
     94          : mEnumeration(aEnumeration), mUnitsPos(aUnitsPos) {
     95        advance();
     96      }
     97 
     98      Iterator& operator++() {
     99        advance();
    100        return *this;
    101      }
    102 
    103      // The post-increment operator would return an invalid iterator, so it's
    104      // not implemented.
    105      Iterator operator++(int) = delete;
    106 
    107      bool operator==(const Iterator& aOther) const {
    108        // It's an error to compare an iterator against an iterator from a
    109        // different enumeration.
    110        MOZ_ASSERT(&mEnumeration == &aOther.mEnumeration);
    111 
    112        return mUnitsPos == aOther.mUnitsPos && mTypeSize == aOther.mTypeSize &&
    113               mTypePos == aOther.mTypePos && mHasError == aOther.mHasError;
    114      }
    115 
    116      bool operator!=(const Iterator& aOther) const {
    117        return !(*this == aOther);
    118      }
    119 
    120      value_type operator*() const;
    121    };
    122 
    123    friend class Iterator;
    124 
    125    // std::iterator begin() and end() methods.
    126 
    127    /**
    128     * Return an iterator pointing to the start of the "units" table.
    129     */
    130    Iterator begin() { return Iterator(*this, 0); }
    131 
    132    /**
    133     * Return an iterator pointing to the end of the "units" table.
    134     */
    135    Iterator end() { return Iterator(*this, mUnitsSize); }
    136 
    137    /**
    138     * Create a new measurement unit enumeration.
    139     */
    140    static Result<Enumeration, ICUError> TryCreate();
    141  };
    142 
    143  /**
    144   * Return an enumeration over all available measurement units.
    145   */
    146  static Result<Enumeration, ICUError> GetAvailable() {
    147    return Enumeration::TryCreate();
    148  }
    149 };
    150 
    151 }  // namespace mozilla::intl
    152 
    153 #endif