mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-05 07:39:16 +00:00
This uses ICU for the Intl.NumberFormat `format` and `formatToParts` prototypes. It does not yet port the range formatter prototypes. Most of the new code in LibLocale/NumberFormat is simply mapping from ECMA-402 types to ICU types. Beyond that, the only algorithmic change is that we have to mutate the output from ICU for `formatToParts` to match what is expected by ECMA-402. This is explained in NumberFormat.cpp in `flatten_partitions`. This lets us remove most data from our number format generator. All that remains are numbering system digits and symbols, which are relied upon still for other interfaces (e.g. Intl.DateTimeFormat). So they will be removed in a future patch. Note: All of the changes to the test files in this patch are now aligned with both Chrome and Safari.
106 lines
2.6 KiB
C++
106 lines
2.6 KiB
C++
/*
|
|
* Copyright (c) 2022-2024, Tim Flynn <trflynn89@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibJS/Runtime/Intl/MathematicalValue.h>
|
|
|
|
namespace JS::Intl {
|
|
|
|
bool MathematicalValue::is_number() const
|
|
{
|
|
return m_value.has<double>();
|
|
}
|
|
|
|
double MathematicalValue::as_number() const
|
|
{
|
|
VERIFY(is_number());
|
|
return m_value.get<double>();
|
|
}
|
|
|
|
bool MathematicalValue::is_bigint() const
|
|
{
|
|
return m_value.has<Crypto::SignedBigInteger>();
|
|
}
|
|
|
|
Crypto::SignedBigInteger const& MathematicalValue::as_bigint() const
|
|
{
|
|
VERIFY(is_bigint());
|
|
return m_value.get<Crypto::SignedBigInteger>();
|
|
}
|
|
|
|
bool MathematicalValue::is_mathematical_value() const
|
|
{
|
|
return is_number() || is_bigint();
|
|
}
|
|
|
|
bool MathematicalValue::is_positive_infinity() const
|
|
{
|
|
if (is_mathematical_value())
|
|
return false;
|
|
return m_value.get<Symbol>() == Symbol::PositiveInfinity;
|
|
}
|
|
|
|
bool MathematicalValue::is_negative_infinity() const
|
|
{
|
|
if (is_mathematical_value())
|
|
return false;
|
|
return m_value.get<Symbol>() == Symbol::NegativeInfinity;
|
|
}
|
|
|
|
bool MathematicalValue::is_negative_zero() const
|
|
{
|
|
if (is_mathematical_value())
|
|
return false;
|
|
return m_value.get<Symbol>() == Symbol::NegativeZero;
|
|
}
|
|
|
|
bool MathematicalValue::is_nan() const
|
|
{
|
|
if (is_mathematical_value())
|
|
return false;
|
|
return m_value.get<Symbol>() == Symbol::NotANumber;
|
|
}
|
|
|
|
::Locale::NumberFormat::Value MathematicalValue::to_value() const
|
|
{
|
|
return m_value.visit(
|
|
[](double value) -> ::Locale::NumberFormat::Value {
|
|
return value;
|
|
},
|
|
[](Crypto::SignedBigInteger const& value) -> ::Locale::NumberFormat::Value {
|
|
return MUST(value.to_base(10));
|
|
},
|
|
[](auto symbol) -> ::Locale::NumberFormat::Value {
|
|
switch (symbol) {
|
|
case Symbol::PositiveInfinity:
|
|
return js_infinity().as_double();
|
|
case Symbol::NegativeInfinity:
|
|
return js_negative_infinity().as_double();
|
|
case Symbol::NegativeZero:
|
|
return -0.0;
|
|
case Symbol::NotANumber:
|
|
return js_nan().as_double();
|
|
}
|
|
|
|
VERIFY_NOT_REACHED();
|
|
});
|
|
}
|
|
|
|
MathematicalValue::ValueType MathematicalValue::value_from_number(double number)
|
|
{
|
|
Value value(number);
|
|
|
|
if (value.is_positive_infinity())
|
|
return Symbol::PositiveInfinity;
|
|
if (value.is_negative_infinity())
|
|
return Symbol::NegativeInfinity;
|
|
if (value.is_negative_zero())
|
|
return Symbol::NegativeZero;
|
|
if (value.is_nan())
|
|
return Symbol::NotANumber;
|
|
return number;
|
|
}
|
|
|
|
}
|