Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* 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 builtin_intl_IntlMathematicalValue_h
#define builtin_intl_IntlMathematicalValue_h
#include <stddef.h>
#include <string_view>
#include "js/GCAPI.h"
#include "js/RootingAPI.h"
#include "js/TypeDecls.h"
#include "js/Utility.h"
#include "js/Value.h"
class JSLinearString;
namespace js::intl {
class IntlMathematicalValueString;
class IntlMathematicalValueStringView;
/**
* An Intl mathematical value is either a numeric value or a string which can
* be parsed as `StringNumericLiteral`.
*/
class IntlMathematicalValue final {
JS::Value value_{};
JSLinearString* toLinearString(JSContext* cx) const;
public:
IntlMathematicalValue() = default;
explicit IntlMathematicalValue(JS::Value value) : value_(value) {
MOZ_ASSERT(value.isNumeric() || value.isString());
}
explicit IntlMathematicalValue(JS::BigInt* bigInt)
: value_(JS::BigIntValue(bigInt)) {}
bool isNumber() const { return value_.isNumber(); }
bool isBigInt() const { return value_.isBigInt(); }
bool isNaN() const { return value_.isNaN(); }
double toNumber() const { return value_.toNumber(); }
JS::BigInt* toBigInt() const { return value_.toBigInt(); }
bool isRepresentableAsDouble(double* result) const;
[[nodiscard]] IntlMathematicalValueString toString(JSContext* cx) const;
void trace(JSTracer* trc);
};
/**
* Wrapper around a string produced from `IntlMathematicalValue`.
*/
class IntlMathematicalValueString final {
JSLinearString* string_ = nullptr;
explicit IntlMathematicalValueString(JSLinearString* string)
: string_(string) {}
friend class IntlMathematicalValue;
public:
IntlMathematicalValueString() = default;
explicit operator bool() const { return !!string_; }
[[nodiscard]] IntlMathematicalValueStringView asView(
JSContext* cx, const JS::AutoCheckCannotGC& nogc) const;
void trace(JSTracer* trc);
};
/**
* View to the string characters of `IntlMathematicalValueString`.
*/
class IntlMathematicalValueStringView final {
std::string_view view_{};
// Two-byte strings have to be copied into a separate buffer.
JS::UniqueChars latin1_{};
public:
IntlMathematicalValueStringView() = default;
explicit IntlMathematicalValueStringView(std::string_view view,
JS::UniqueChars latin1 = nullptr)
: view_(view), latin1_(std::move(latin1)) {}
explicit operator bool() const { return !view_.empty(); }
operator std::string_view() const { return view_; }
};
inline IntlMathematicalValueString IntlMathematicalValue::toString(
JSContext* cx) const {
return IntlMathematicalValueString{toLinearString(cx)};
}
/**
* 15.5.16 ToIntlMathematicalValue ( value )
*
* ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
*/
bool ToIntlMathematicalValue(JSContext* cx, JS::Handle<JS::Value> value,
JS::MutableHandle<IntlMathematicalValue> result);
} // namespace js::intl
namespace js {
template <typename Wrapper>
class WrappedPtrOperations<intl::IntlMathematicalValue, Wrapper> {
const intl::IntlMathematicalValue& container() const {
return static_cast<const Wrapper*>(this)->get();
}
public:
bool isNumber() const { return container().isNumber(); }
bool isBigInt() const { return container().isBigInt(); }
bool isNaN() const { return container().isNaN(); }
double toNumber() const { return container().toNumber(); }
JS::BigInt* toBigInt() const { return container().toBigInt(); }
bool isRepresentableAsDouble(double* result) const {
return container().isRepresentableAsDouble(result);
}
[[nodiscard]] auto toString(JSContext* cx) const {
return container().toString(cx);
}
};
template <typename Wrapper>
class WrappedPtrOperations<intl::IntlMathematicalValueString, Wrapper> {
const intl::IntlMathematicalValueString& container() const {
return static_cast<const Wrapper*>(this)->get();
}
public:
explicit operator bool() const { return bool(container()); }
auto asView(JSContext* cx, const JS::AutoCheckCannotGC& nogc) const {
return container().asView(cx, nogc);
}
};
} // namespace js
#endif /* builtin_intl_IntlMathematicalValue_h */