diff options
Diffstat (limited to 'Userland/Libraries/LibPDF/Object.h')
-rw-r--r-- | Userland/Libraries/LibPDF/Object.h | 81 |
1 files changed, 55 insertions, 26 deletions
diff --git a/Userland/Libraries/LibPDF/Object.h b/Userland/Libraries/LibPDF/Object.h index 5774434ef0..71b6bb9a4c 100644 --- a/Userland/Libraries/LibPDF/Object.h +++ b/Userland/Libraries/LibPDF/Object.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org> + * Copyright (c) 2021-2022, Matthew Olsson <mattco@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -11,9 +11,29 @@ #include <AK/Format.h> #include <AK/RefCounted.h> #include <AK/SourceLocation.h> +#include <LibPDF/Error.h> #include <LibPDF/Forward.h> #include <LibPDF/Value.h> +#ifdef PDF_DEBUG +namespace { + +template<PDF::IsObject T> +const char* object_name() +{ +# define ENUMERATE_TYPE(class_name, snake_name) \ + if constexpr (IsSame<PDF::class_name, T>) { \ + return #class_name; \ + } + ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE) +# undef ENUMERATE_TYPE + + VERIFY_NOT_REACHED(); +} + +} +#endif + namespace PDF { class Object : public RefCounted<Object> { @@ -23,39 +43,48 @@ public: [[nodiscard]] ALWAYS_INLINE u32 generation_index() const { return m_generation_index; } ALWAYS_INLINE void set_generation_index(u32 generation_index) { m_generation_index = generation_index; } -#define DEFINE_ID(_, name) \ - virtual bool is_##name() const { return false; } - ENUMERATE_OBJECT_TYPES(DEFINE_ID) -#undef DEFINE_ID - - virtual const char* type_name() const = 0; - virtual String to_string(int indent) const = 0; + template<IsObject T> + bool is() const requires(!IsSame<T, Object>) + { +#define ENUMERATE_TYPE(class_name, snake_name) \ + if constexpr (IsSame<class_name, T>) { \ + return is_##snake_name(); \ + } + ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE) +#undef ENUMERATE_TYPE -private: - u32 m_generation_index { 0 }; -}; + VERIFY_NOT_REACHED(); + } -template<IsObject To, IsObject From> -[[nodiscard]] ALWAYS_INLINE static NonnullRefPtr<To> object_cast(NonnullRefPtr<From> obj + template<IsObject T> + [[nodiscard]] ALWAYS_INLINE NonnullRefPtr<T> cast( #ifdef PDF_DEBUG - , - SourceLocation loc = SourceLocation::current() + SourceLocation loc = SourceLocation::current() #endif -) -{ + ) const requires(!IsSame<T, Object>) + { #ifdef PDF_DEBUG -# define ENUMERATE_TYPES(class_name, snake_name) \ - if constexpr (IsSame<To, class_name>) { \ - if (!obj->is_##snake_name()) { \ - dbgln("{} invalid cast from type {} to type " #snake_name, loc, obj->type_name()); \ - } \ + if (!is<T>()) { + dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>()); + VERIFY_NOT_REACHED(); } - ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPES) -# undef ENUMERATE_TYPES #endif - return static_ptr_cast<To>(obj); -} + return NonnullRefPtr<T>(static_cast<T const&>(*this)); + } + + virtual const char* type_name() const = 0; + virtual String to_string(int indent) const = 0; + +protected: +#define ENUMERATE_TYPE(_, name) \ + virtual bool is_##name() const { return false; } + ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE) +#undef ENUMERATE_TYPE + +private: + u32 m_generation_index { 0 }; +}; } |