Number.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Types.h>
  8. #include <math.h>
  9. namespace Web::CSS {
  10. class Number {
  11. public:
  12. enum class Type {
  13. Number,
  14. IntegerWithExplicitSign, // This only exists for the nightmarish An+B parsing algorithm
  15. Integer
  16. };
  17. Number()
  18. : m_value(0)
  19. , m_type(Type::Number)
  20. {
  21. }
  22. Number(Type type, float value)
  23. : m_value(value)
  24. , m_type(type)
  25. {
  26. }
  27. float value() const { return m_value; }
  28. i64 integer_value() const
  29. {
  30. // https://www.w3.org/TR/css-values-4/#numeric-types
  31. // When a value cannot be explicitly supported due to range/precision limitations, it must be converted
  32. // to the closest value supported by the implementation, but how the implementation defines "closest"
  33. // is explicitly undefined as well.
  34. return llroundf(m_value);
  35. }
  36. bool is_integer() const { return m_type == Type::Integer || m_type == Type::IntegerWithExplicitSign; }
  37. bool is_integer_with_explicit_sign() const { return m_type == Type::IntegerWithExplicitSign; }
  38. Number operator+(Number const& other) const
  39. {
  40. if (is_integer() && other.is_integer())
  41. return { Type::Integer, m_value + other.m_value };
  42. return { Type::Number, m_value + other.m_value };
  43. }
  44. Number operator-(Number const& other) const
  45. {
  46. if (is_integer() && other.is_integer())
  47. return { Type::Integer, m_value - other.m_value };
  48. return { Type::Number, m_value - other.m_value };
  49. }
  50. Number operator*(Number const& other) const
  51. {
  52. if (is_integer() && other.is_integer())
  53. return { Type::Integer, m_value * other.m_value };
  54. return { Type::Number, m_value * other.m_value };
  55. }
  56. Number operator/(Number const& other) const
  57. {
  58. return { Type::Number, m_value / other.m_value };
  59. }
  60. private:
  61. float m_value { 0 };
  62. Type m_type;
  63. };
  64. }