/* -*- 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_temporal_TemporalFields_h #define builtin_temporal_TemporalFields_h #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" #include #include "jstypes.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" #include "js/Value.h" class JS_PUBLIC_API JSTracer; namespace js { class PlainObject; } namespace js::temporal { enum class TemporalField { Year, Month, MonthCode, Day, Hour, Minute, Second, Millisecond, Microsecond, Nanosecond, Offset, Era, EraYear, TimeZone, }; // Default values are specified in Table 15 [1]. `undefined` is replaced with // an appropriate value based on the type, for example `double` fields use // NaN whereas pointer fields use nullptr. // // [1] struct MOZ_STACK_CLASS TemporalFields final { double year = mozilla::UnspecifiedNaN(); double month = mozilla::UnspecifiedNaN(); JSString* monthCode = nullptr; double day = mozilla::UnspecifiedNaN(); double hour = 0; double minute = 0; double second = 0; double millisecond = 0; double microsecond = 0; double nanosecond = 0; JSString* offset = nullptr; JSString* era = nullptr; double eraYear = mozilla::UnspecifiedNaN(); JS::Value timeZone = JS::UndefinedValue(); TemporalFields() = default; void trace(JSTracer* trc); }; } // namespace js::temporal namespace js { template class WrappedPtrOperations { const temporal::TemporalFields& fields() const { return static_cast(this)->get(); } public: double year() const { return fields().year; } double month() const { return fields().month; } double day() const { return fields().day; } double hour() const { return fields().hour; } double minute() const { return fields().minute; } double second() const { return fields().second; } double millisecond() const { return fields().millisecond; } double microsecond() const { return fields().microsecond; } double nanosecond() const { return fields().nanosecond; } double eraYear() const { return fields().eraYear; } JS::Handle monthCode() const { return JS::Handle::fromMarkedLocation(&fields().monthCode); } JS::Handle offset() const { return JS::Handle::fromMarkedLocation(&fields().offset); } JS::Handle era() const { return JS::Handle::fromMarkedLocation(&fields().era); } JS::Handle timeZone() const { return JS::Handle::fromMarkedLocation(&fields().timeZone); } }; template class MutableWrappedPtrOperations : public WrappedPtrOperations { temporal::TemporalFields& fields() { return static_cast(this)->get(); } public: double& year() { return fields().year; } double& month() { return fields().month; } double& day() { return fields().day; } double& hour() { return fields().hour; } double& minute() { return fields().minute; } double& second() { return fields().second; } double& millisecond() { return fields().millisecond; } double& microsecond() { return fields().microsecond; } double& nanosecond() { return fields().nanosecond; } double& eraYear() { return fields().eraYear; } JS::MutableHandle monthCode() { return JS::MutableHandle::fromMarkedLocation( &fields().monthCode); } JS::MutableHandle offset() { return JS::MutableHandle::fromMarkedLocation(&fields().offset); } JS::MutableHandle era() { return JS::MutableHandle::fromMarkedLocation(&fields().era); } JS::MutableHandle timeZone() { return JS::MutableHandle::fromMarkedLocation(&fields().timeZone); } }; } // namespace js namespace js::temporal { /** * PrepareTemporalFields ( fields, fieldNames, requiredFields [ , * duplicateBehaviour ] ) */ bool PrepareTemporalFields(JSContext* cx, JS::Handle fields, std::initializer_list fieldNames, std::initializer_list requiredFields, JS::MutableHandle result); using TemporalFieldNames = JS::StackGCVector; /** * PrepareTemporalFields ( fields, fieldNames, requiredFields [ , * duplicateBehaviour ] ) */ PlainObject* PrepareTemporalFields(JSContext* cx, JS::Handle fields, JS::Handle fieldNames); /** * PrepareTemporalFields ( fields, fieldNames, requiredFields [ , * duplicateBehaviour ] ) */ PlainObject* PrepareTemporalFields( JSContext* cx, JS::Handle fields, JS::Handle fieldNames, std::initializer_list requiredFields); /** * PrepareTemporalFields ( fields, fieldNames, requiredFields [ , * duplicateBehaviour ] ) */ PlainObject* PreparePartialTemporalFields( JSContext* cx, JS::Handle fields, JS::Handle fieldNames); [[nodiscard]] bool ConcatTemporalFieldNames( const TemporalFieldNames& receiverFieldNames, const TemporalFieldNames& inputFieldNames, TemporalFieldNames& concatenatedFieldNames); [[nodiscard]] bool AppendSorted( JSContext* cx, TemporalFieldNames& fieldNames, std::initializer_list additionalNames); [[nodiscard]] bool SortTemporalFieldNames(JSContext* cx, TemporalFieldNames& fieldNames); } /* namespace js::temporal */ #endif /* builtin_temporal_TemporalFields_h */