CanonicalIndex.h 1.3 KB

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