diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /intl/components/src/MeasureUnit.h | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'intl/components/src/MeasureUnit.h')
-rw-r--r-- | intl/components/src/MeasureUnit.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/intl/components/src/MeasureUnit.h b/intl/components/src/MeasureUnit.h new file mode 100644 index 0000000000..8a8cf1629a --- /dev/null +++ b/intl/components/src/MeasureUnit.h @@ -0,0 +1,155 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef intl_components_MeasureUnit_h_ +#define intl_components_MeasureUnit_h_ + +#include "mozilla/Assertions.h" +#include "mozilla/intl/ICU4CGlue.h" +#include "mozilla/intl/ICUError.h" +#include "mozilla/Result.h" +#include "mozilla/Span.h" +#include "mozilla/UniquePtr.h" + +#include <iterator> +#include <stddef.h> +#include <stdint.h> +#include <utility> + +struct UResourceBundle; + +namespace mozilla::intl { + +/** + * This component is a Mozilla-focused API for working with measurement units in + * internationalization code. It is used in coordination with other operations + * such as number formatting. + */ +class MeasureUnit final { + class UResourceBundleDeleter { + public: + void operator()(UResourceBundle* aPtr); + }; + + using UniqueUResourceBundle = + UniquePtr<UResourceBundle, UResourceBundleDeleter>; + + public: + MeasureUnit() = delete; + + class Enumeration final { + // Resource bundle for the root locale. + UniqueUResourceBundle mRootLocale = nullptr; + + // Resource bundle for the root locale's "units" resource table. + UniqueUResourceBundle mUnits = nullptr; + + // The overall amount of available units. + int32_t mUnitsSize = 0; + + public: + Enumeration(UniqueUResourceBundle aRootLocale, + UniqueUResourceBundle aUnits); + + class Iterator { + public: + // std::iterator traits. + using iterator_category = std::input_iterator_tag; + using value_type = SpanResult<char>; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + + private: + const Enumeration& mEnumeration; + + // Resource bundle to a measurement type within the "units" table. + // + // Measurement types describe various categories, like "area", "length", + // or "mass". + UniqueUResourceBundle mType = nullptr; + + // Resource bundle to a specific subtype within the type table. + // + // Measurement subtypes describe concrete measure units, like "acre", + // "meter", or "kilogram". + UniqueUResourceBundle mSubtype = nullptr; + + // The next position within the "units" table. + int32_t mUnitsPos = 0; + + // The overall amount of types within the |mType| table. + int32_t mTypeSize = 0; + + // The next position within the |mType| table. + int32_t mTypePos = 0; + + // Flag set when an ICU error has occurred. All further operations on this + // iterator will return an error result when this flag is set. + bool mHasError = false; + + void advance(); + + public: + Iterator(const Enumeration& aEnumeration, int32_t aUnitsPos) + : mEnumeration(aEnumeration), mUnitsPos(aUnitsPos) { + advance(); + } + + Iterator& operator++() { + advance(); + return *this; + } + + // The post-increment operator would return an invalid iterator, so it's + // not implemented. + Iterator operator++(int) = delete; + + bool operator==(const Iterator& aOther) const { + // It's an error to compare an iterator against an iterator from a + // different enumeration. + MOZ_ASSERT(&mEnumeration == &aOther.mEnumeration); + + return mUnitsPos == aOther.mUnitsPos && mTypeSize == aOther.mTypeSize && + mTypePos == aOther.mTypePos && mHasError == aOther.mHasError; + } + + bool operator!=(const Iterator& aOther) const { + return !(*this == aOther); + } + + value_type operator*() const; + }; + + friend class Iterator; + + // std::iterator begin() and end() methods. + + /** + * Return an iterator pointing to the start of the "units" table. + */ + Iterator begin() { return Iterator(*this, 0); } + + /** + * Return an iterator pointing to the end of the "units" table. + */ + Iterator end() { return Iterator(*this, mUnitsSize); } + + /** + * Create a new measurement unit enumeration. + */ + static Result<Enumeration, ICUError> TryCreate(); + }; + + /** + * Return an enumeration over all available measurement units. + */ + static Result<Enumeration, ICUError> GetAvailable() { + return Enumeration::TryCreate(); + } +}; + +} // namespace mozilla::intl + +#endif |