Object.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (c) 2021-2022, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Debug.h>
  8. #include <AK/FlyString.h>
  9. #include <AK/Format.h>
  10. #include <AK/RefCounted.h>
  11. #include <AK/SourceLocation.h>
  12. #include <LibPDF/Error.h>
  13. #include <LibPDF/Forward.h>
  14. #include <LibPDF/Value.h>
  15. #ifdef PDF_DEBUG
  16. namespace {
  17. template<PDF::IsObject T>
  18. char const* object_name()
  19. {
  20. # define ENUMERATE_TYPE(class_name, snake_name) \
  21. if constexpr (IsSame<PDF::class_name, T>) { \
  22. return #class_name; \
  23. }
  24. ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
  25. # undef ENUMERATE_TYPE
  26. VERIFY_NOT_REACHED();
  27. }
  28. }
  29. #endif
  30. namespace PDF {
  31. class Object : public RefCounted<Object> {
  32. public:
  33. virtual ~Object() = default;
  34. [[nodiscard]] ALWAYS_INLINE u32 generation_index() const { return m_generation_index; }
  35. ALWAYS_INLINE void set_generation_index(u32 generation_index) { m_generation_index = generation_index; }
  36. template<IsObject T>
  37. bool is() const requires(!IsSame<T, Object>)
  38. {
  39. #define ENUMERATE_TYPE(class_name, snake_name) \
  40. if constexpr (IsSame<class_name, T>) { \
  41. return is_##snake_name(); \
  42. }
  43. ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
  44. #undef ENUMERATE_TYPE
  45. VERIFY_NOT_REACHED();
  46. }
  47. template<IsObject T>
  48. [[nodiscard]] ALWAYS_INLINE NonnullRefPtr<T> cast(
  49. #ifdef PDF_DEBUG
  50. SourceLocation loc = SourceLocation::current()
  51. #endif
  52. ) const requires(!IsSame<T, Object>)
  53. {
  54. #ifdef PDF_DEBUG
  55. if (!is<T>()) {
  56. dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
  57. VERIFY_NOT_REACHED();
  58. }
  59. #endif
  60. return NonnullRefPtr<T>(static_cast<T const&>(*this));
  61. }
  62. virtual char const* type_name() const = 0;
  63. virtual String to_string(int indent) const = 0;
  64. protected:
  65. #define ENUMERATE_TYPE(_, name) \
  66. virtual bool is_##name() const { return false; }
  67. ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
  68. #undef ENUMERATE_TYPE
  69. private:
  70. u32 m_generation_index { 0 };
  71. };
  72. }
  73. namespace AK {
  74. template<PDF::IsObject T>
  75. struct Formatter<T> : Formatter<StringView> {
  76. ErrorOr<void> format(FormatBuilder& builder, T const& object)
  77. {
  78. return Formatter<StringView>::format(builder, object.to_string(0));
  79. }
  80. };
  81. template<PDF::IsObject T>
  82. struct Formatter<NonnullRefPtr<T>> : Formatter<T> {
  83. ErrorOr<void> format(FormatBuilder& builder, NonnullRefPtr<T> const& object)
  84. {
  85. return Formatter<T>::format(builder, *object);
  86. }
  87. };
  88. }