Object.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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/DeprecatedFlyString.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. #ifdef PDF_DEBUG
  15. namespace {
  16. template<PDF::IsObject T>
  17. char const* object_name()
  18. {
  19. # define ENUMERATE_TYPE(class_name, snake_name) \
  20. if constexpr (IsSame<PDF::class_name, T>) { \
  21. return #class_name; \
  22. }
  23. ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
  24. # undef ENUMERATE_TYPE
  25. VERIFY_NOT_REACHED();
  26. }
  27. }
  28. #endif
  29. namespace PDF {
  30. class Object : public RefCounted<Object> {
  31. public:
  32. virtual ~Object() = default;
  33. [[nodiscard]] ALWAYS_INLINE u32 generation_index() const { return m_generation_index; }
  34. ALWAYS_INLINE void set_generation_index(u32 generation_index) { m_generation_index = generation_index; }
  35. template<IsObject T>
  36. bool is() const
  37. 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. )
  53. requires(!IsSame<T, Object>)
  54. {
  55. #ifdef PDF_DEBUG
  56. if (!is<T>()) {
  57. dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
  58. VERIFY_NOT_REACHED();
  59. }
  60. #endif
  61. return NonnullRefPtr<T>(static_cast<T&>(*this));
  62. }
  63. virtual char const* type_name() const = 0;
  64. virtual DeprecatedString to_deprecated_string(int indent) const = 0;
  65. protected:
  66. #define ENUMERATE_TYPE(_, name) \
  67. virtual bool is_##name() const \
  68. { \
  69. return false; \
  70. }
  71. ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
  72. #undef ENUMERATE_TYPE
  73. private:
  74. u32 m_generation_index { 0 };
  75. };
  76. }
  77. namespace AK {
  78. template<PDF::IsObject T>
  79. struct Formatter<T> : Formatter<StringView> {
  80. ErrorOr<void> format(FormatBuilder& builder, T const& object)
  81. {
  82. return Formatter<StringView>::format(builder, object.to_deprecated_string(0));
  83. }
  84. };
  85. template<PDF::IsObject T>
  86. struct Formatter<NonnullRefPtr<T>> : Formatter<T> {
  87. ErrorOr<void> format(FormatBuilder& builder, NonnullRefPtr<T> const& object)
  88. {
  89. return Formatter<T>::format(builder, *object);
  90. }
  91. };
  92. }