diff --git a/poincare/include/poincare/unit.h b/poincare/include/poincare/unit.h index 689203e4a..3be06ccf6 100644 --- a/poincare/include/poincare/unit.h +++ b/poincare/include/poincare/unit.h @@ -38,7 +38,6 @@ public: m_symbol(symbol), m_exponent(exponent) {} - inline bool operator==(const Prefix& p) const { return m_exponent == p.m_exponent && strcmp(m_symbol, p.m_symbol) == 0; } const char * symbol() const { return m_symbol; } int8_t exponent() const { return m_exponent; } int serialize(char * buffer, int bufferSize) const; @@ -57,19 +56,19 @@ public: Yes }; template - constexpr Representative(const char * rootSymbol, const char * definition, const Prefixable prefixable, const Prefix (&outputPrefixes)[N]) : + constexpr Representative(const char * rootSymbol, const char * definition, const Prefixable prefixable, const Prefix * const (&outputPrefixes)[N]) : m_rootSymbol(rootSymbol), m_definition(definition), m_prefixable(prefixable), m_outputPrefixes(outputPrefixes), - m_outputPrefixesUpperBound(outputPrefixes + N) + m_outputPrefixesLength(N) { } const char * rootSymbol() const { return m_rootSymbol; } const char * definition() const { return m_definition; } bool isPrefixable() const { return m_prefixable == Prefixable::Yes; } - const Prefix * outputPrefixes() const { return m_outputPrefixes; } - const Prefix * outputPrefixesUpperBound() const { return m_outputPrefixesUpperBound; } + const Prefix * const * outputPrefixes() const { return m_outputPrefixes; } + size_t outputPrefixesLength() const { return m_outputPrefixesLength; } bool canParse(const char * symbol, size_t length, const Prefix * * prefix) const; int serialize(char * buffer, int bufferSize, const Prefix * prefix) const; @@ -78,8 +77,8 @@ public: const char * m_rootSymbol; const char * m_definition; const Prefixable m_prefixable; - const Prefix * m_outputPrefixes; - const Prefix * m_outputPrefixesUpperBound; + const Prefix * const * m_outputPrefixes; + const size_t m_outputPrefixesLength; }; class Dimension { @@ -203,58 +202,57 @@ public: MegaPrefix = Prefix("M", 6), GigaPrefix = Prefix("G", 9), TeraPrefix = Prefix("T", 12); - static constexpr const Prefix - NoPrefix[] = { - EmptyPrefix - }, - NegativeLongScalePrefixes[] = { - PicoPrefix, - NanoPrefix, - MicroPrefix, - MilliPrefix, - EmptyPrefix, - }, - PositiveLongScalePrefixes[] = { - EmptyPrefix, - KiloPrefix, - MegaPrefix, - GigaPrefix, - TeraPrefix, - }, - LongScalePrefixes[] = { - PicoPrefix, - NanoPrefix, - MicroPrefix, - MilliPrefix, - EmptyPrefix, - KiloPrefix, - MegaPrefix, - GigaPrefix, - TeraPrefix, - }, - NegativePrefixes[] = { - PicoPrefix, - NanoPrefix, - MicroPrefix, - MilliPrefix, - CentiPrefix, - DeciPrefix, - EmptyPrefix, - }, - AllPrefixes[] = { - PicoPrefix, - NanoPrefix, - MicroPrefix, - MilliPrefix, - CentiPrefix, - DeciPrefix, - EmptyPrefix, - DecaPrefix, - HectoPrefix, - KiloPrefix, - MegaPrefix, - GigaPrefix, - TeraPrefix, + static constexpr const Prefix * NoPrefix[] = { + &EmptyPrefix + }; + static constexpr const Prefix * NegativeLongScalePrefixes[] = { + &PicoPrefix, + &NanoPrefix, + &MicroPrefix, + &MilliPrefix, + &EmptyPrefix, + }; + static constexpr const Prefix * PositiveLongScalePrefixes[] = { + &EmptyPrefix, + &KiloPrefix, + &MegaPrefix, + &GigaPrefix, + &TeraPrefix, + }; + static constexpr const Prefix * LongScalePrefixes[] = { + &PicoPrefix, + &NanoPrefix, + &MicroPrefix, + &MilliPrefix, + &EmptyPrefix, + &KiloPrefix, + &MegaPrefix, + &GigaPrefix, + &TeraPrefix, + }; + static constexpr const Prefix * NegativePrefixes[] = { + &PicoPrefix, + &NanoPrefix, + &MicroPrefix, + &MilliPrefix, + &CentiPrefix, + &DeciPrefix, + &EmptyPrefix, + }; + static constexpr const Prefix * AllPrefixes[] = { + &PicoPrefix, + &NanoPrefix, + &MicroPrefix, + &MilliPrefix, + &CentiPrefix, + &DeciPrefix, + &EmptyPrefix, + &DecaPrefix, + &HectoPrefix, + &KiloPrefix, + &MegaPrefix, + &GigaPrefix, + &TeraPrefix, }; static constexpr size_t NumberOfBaseUnits = UnitNode::NumberOfBaseUnits; static constexpr const Representative diff --git a/poincare/src/unit.cpp b/poincare/src/unit.cpp index 8082cfef5..97b05093a 100644 --- a/poincare/src/unit.cpp +++ b/poincare/src/unit.cpp @@ -30,8 +30,9 @@ bool UnitNode::Representative::canParse(const char * symbol, size_t length, *prefix = &Unit::EmptyPrefix; return length == 0; } - const Prefix * pre = Unit::AllPrefixes; - while (pre < Unit::AllPrefixes + sizeof(Unit::AllPrefixes)/sizeof(Unit::Prefix)) { + size_t numberOfPrefixes = sizeof(Unit::AllPrefixes)/sizeof(Unit::Prefix *); + for (size_t i = 0; i < numberOfPrefixes; i++) { + const Prefix * pre = Unit::AllPrefixes[i]; const char * prefixSymbol = pre->symbol(); if (strncmp(symbol, prefixSymbol, length) == 0 && prefixSymbol[length] == 0) @@ -66,7 +67,8 @@ const UnitNode::Prefix * UnitNode::Representative::bestPrefixForValue(double & v * magnitude of 'value'. */ const int orderOfMagnitude = IEEE754::exponentBase10(std::fabs(value)); - for (const Prefix * pre = m_outputPrefixes; pre < m_outputPrefixesUpperBound; pre++) { + for (size_t i = 0; i < m_outputPrefixesLength; i++) { + const Prefix * pre = m_outputPrefixes[i]; unsigned int newDiff = absInt(orderOfMagnitude - pre->exponent() * exponent); if (newDiff < diff) { diff = newDiff; @@ -234,13 +236,12 @@ constexpr const Unit::Prefix Unit::MegaPrefix, Unit::GigaPrefix, Unit::TeraPrefix; -constexpr const Unit::Prefix - Unit::NoPrefix[], - Unit::NegativeLongScalePrefixes[], - Unit::PositiveLongScalePrefixes[], - Unit::LongScalePrefixes[], - Unit::NegativePrefixes[], - Unit::AllPrefixes[]; +constexpr const Unit::Prefix * const Unit::NoPrefix[]; +constexpr const Unit::Prefix * const Unit::NegativeLongScalePrefixes[]; +constexpr const Unit::Prefix * const Unit::PositiveLongScalePrefixes[]; +constexpr const Unit::Prefix * const Unit::LongScalePrefixes[]; +constexpr const Unit::Prefix * const Unit::NegativePrefixes[]; +constexpr const Unit::Prefix * const Unit::AllPrefixes[]; constexpr const Unit::Representative Unit::TimeRepresentatives[], Unit::DistanceRepresentatives[], @@ -392,16 +393,16 @@ Expression Unit::removeUnit(Expression * unit) { } bool Unit::isSecond() const { - return node()->dimension() == TimeDimension && node()->representative() == SecondRepresentative && *(node()->prefix()) == EmptyPrefix; + return node()->dimension() == TimeDimension && node()->representative() == SecondRepresentative && node()->prefix() == &EmptyPrefix; } bool Unit::isMeter() const { - return node()->dimension() == DistanceDimension && node()->representative() == MeterRepresentative && *(node()->prefix()) == EmptyPrefix; + return node()->dimension() == DistanceDimension && node()->representative() == MeterRepresentative && node()->prefix() == &EmptyPrefix; } bool Unit::isKilogram() const { - return node()->dimension() == MassDimension && node()->representative() == KilogramRepresentative && *(node()->prefix()) == KiloPrefix; + return node()->dimension() == MassDimension && node()->representative() == KilogramRepresentative && node()->prefix() == &KiloPrefix; } bool Unit::IsISSpeed(Expression & e) { diff --git a/poincare/test/parsing.cpp b/poincare/test/parsing.cpp index 8ed79c0b8..4ee1a88e1 100644 --- a/poincare/test/parsing.cpp +++ b/poincare/test/parsing.cpp @@ -294,7 +294,9 @@ QUIZ_CASE(poincare_parsing_units) { Expression unit = parse_expression(buffer, nullptr, false); quiz_assert_print_if_failure(unit.type() == ExpressionNode::Type::Unit, "Should be parsed as a Unit"); if (rep->isPrefixable()) { - for (const Unit::Prefix * pre = Unit::AllPrefixes; pre < Unit::AllPrefixes + sizeof(Unit::AllPrefixes)/sizeof(Unit::Prefix); pre++) { + size_t numberOfPrefixes = sizeof(Unit::AllPrefixes)/sizeof(Unit::Prefix *); + for (size_t i = 0; i < numberOfPrefixes; i++) { + const Unit::Prefix * pre = Unit::AllPrefixes[i]; Unit::Builder(dim, rep, pre).serialize(buffer, bufferSize, Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits); Expression unit = parse_expression(buffer, nullptr, false); quiz_assert_print_if_failure(unit.type() == ExpressionNode::Type::Unit, "Should be parsed as a Unit"); diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index a6f1069fb..309deabbb 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -245,7 +245,8 @@ QUIZ_CASE(poincare_simplification_units) { Unit::Builder(dim, rep, &Unit::EmptyPrefix).serialize(buffer+strlen("1×"), bufferSize-strlen("1×"), Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits); assert_parsed_expression_simplify_to(buffer, buffer); if (rep->isPrefixable()) { - for (const Unit::Prefix * pre = rep->outputPrefixes(); pre < rep->outputPrefixesUpperBound(); pre++) { + for (size_t i = 0; i < rep->outputPrefixesLength(); i++) { + const Unit::Prefix * pre = rep->outputPrefixes()[i]; Unit::Builder(dim, rep, pre).serialize(buffer+strlen("1×"), bufferSize-strlen("1×"), Preferences::PrintFloatMode::Decimal, Preferences::VeryShortNumberOfSignificantDigits); assert_parsed_expression_simplify_to(buffer, buffer); }