/src/serenity/Userland/Libraries/LibJS/Runtime/CanonicalIndex.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2022, the SerenityOS developers. |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/Concepts.h> |
10 | | #include <AK/NumericLimits.h> |
11 | | #include <AK/Types.h> |
12 | | #include <LibJS/Runtime/Completion.h> |
13 | | #include <LibJS/Runtime/VM.h> |
14 | | |
15 | | namespace JS { |
16 | | |
17 | | class CanonicalIndex { |
18 | | public: |
19 | | enum class Type { |
20 | | Index, |
21 | | Numeric, |
22 | | Undefined, |
23 | | }; |
24 | | |
25 | | CanonicalIndex(Type type, u32 index) |
26 | 0 | : m_type(type) |
27 | 0 | , m_index(index) |
28 | 0 | { |
29 | 0 | } |
30 | | |
31 | | template<FloatingPoint T> |
32 | | CanonicalIndex(Type type, T index) = delete; |
33 | | |
34 | | template<FloatingPoint T> |
35 | | static ThrowCompletionOr<CanonicalIndex> from_double(VM& vm, Type type, T index) |
36 | 0 | { |
37 | 0 | if (index < static_cast<double>(NumericLimits<u32>::min())) |
38 | 0 | return vm.throw_completion<RangeError>(ErrorType::TypedArrayInvalidIntegerIndex, index); |
39 | 0 | if (index > static_cast<double>(NumericLimits<u32>::max())) |
40 | 0 | return vm.throw_completion<RangeError>(ErrorType::TypedArrayInvalidIntegerIndex, index); |
41 | | |
42 | 0 | return CanonicalIndex { type, static_cast<u32>(index) }; |
43 | 0 | } |
44 | | |
45 | | u32 as_index() const |
46 | 0 | { |
47 | 0 | VERIFY(is_index()); |
48 | 0 | return m_index; |
49 | 0 | } |
50 | | |
51 | 0 | bool is_index() const { return m_type == Type::Index; } |
52 | 0 | bool is_undefined() const { return m_type == Type::Undefined; } |
53 | | |
54 | | private: |
55 | | Type m_type; |
56 | | u32 m_index; |
57 | | }; |
58 | | |
59 | | } |