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