mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:27:45 +00:00
LibPDF: Replace Value class by AK::Variant
This decreases the memory consumption by LibPDF by 4 bytes per Value, compensating exactly for the increase in an earlier commit. :^)
This commit is contained in:
parent
d344253b08
commit
f84a7e2e22
7 changed files with 132 additions and 243 deletions
|
@ -9,171 +9,79 @@
|
|||
#include <AK/Format.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibPDF/Forward.h>
|
||||
#include <LibPDF/Object.h>
|
||||
#include <LibPDF/Reference.h>
|
||||
|
||||
namespace PDF {
|
||||
|
||||
class Value {
|
||||
class Value : public Variant<Empty, std::nullptr_t, bool, int, float, Reference, NonnullRefPtr<Object>> {
|
||||
public:
|
||||
using Variant::Variant;
|
||||
|
||||
Value()
|
||||
: m_type(Type::Empty)
|
||||
: Variant(Empty())
|
||||
{
|
||||
}
|
||||
|
||||
struct NullTag {
|
||||
};
|
||||
|
||||
Value(NullTag)
|
||||
: m_type(Type::Null)
|
||||
{
|
||||
}
|
||||
|
||||
Value(bool b)
|
||||
: m_type(Type::Bool)
|
||||
{
|
||||
m_as_bool = b;
|
||||
}
|
||||
|
||||
Value(int i)
|
||||
: m_type(Type::Int)
|
||||
{
|
||||
m_as_int = i;
|
||||
}
|
||||
|
||||
Value(float f)
|
||||
: m_type(Type::Float)
|
||||
{
|
||||
m_as_float = f;
|
||||
}
|
||||
|
||||
Value(Reference ref)
|
||||
: m_type(Type::Ref)
|
||||
{
|
||||
m_as_ref = ref;
|
||||
}
|
||||
|
||||
template<IsObject T>
|
||||
Value(RefPtr<T> obj)
|
||||
: m_type(obj ? Type::Object : Type::Empty)
|
||||
Value(RefPtr<T> const& refptr)
|
||||
: Variant(nullptr)
|
||||
{
|
||||
if (obj) {
|
||||
m_as_object = obj;
|
||||
}
|
||||
if (refptr)
|
||||
set<NonnullRefPtr<Object>>(*refptr);
|
||||
}
|
||||
|
||||
template<IsObject T>
|
||||
Value(NonnullRefPtr<T> obj)
|
||||
: m_type(Type::Object)
|
||||
[[nodiscard]] String to_string(int indent = 0) const;
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE bool has_number() const { return has<int>() || has<float>(); }
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE bool has_u32() const
|
||||
{
|
||||
m_as_object = obj;
|
||||
return has<int>() && get<int>() >= 0;
|
||||
}
|
||||
|
||||
Value(Value const& other)
|
||||
[[nodiscard]] ALWAYS_INLINE bool has_u16() const
|
||||
{
|
||||
*this = other;
|
||||
return has<int>() && get<int>() >= 0 && get<int>() < 65536;
|
||||
}
|
||||
|
||||
~Value() = default;
|
||||
|
||||
Value& operator=(Value const& other);
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_empty() const { return m_type == Type::Empty; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_null() const { return m_type == Type::Null; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_bool() const { return m_type == Type::Bool; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_int() const { return m_type == Type::Int; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_float() const { return m_type == Type::Float; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_number() const { return is_int() || is_float(); }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_ref() const { return m_type == Type::Ref; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_object() const { return m_type == Type::Object; }
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE bool as_bool() const
|
||||
[[nodiscard]] ALWAYS_INLINE u32 get_u32() const
|
||||
{
|
||||
VERIFY(is_bool());
|
||||
return m_as_bool;
|
||||
VERIFY(has_u32());
|
||||
return get<int>();
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE int as_int() const
|
||||
[[nodiscard]] ALWAYS_INLINE u16 get_u16() const
|
||||
{
|
||||
VERIFY(is_int());
|
||||
return m_as_int;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_int_type() const
|
||||
{
|
||||
if (!is_int())
|
||||
return false;
|
||||
auto as_int = static_cast<T>(m_as_int);
|
||||
return as_int >= NumericLimits<T>::min() && as_int <= NumericLimits<T>::max();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] ALWAYS_INLINE T as_int_type() const
|
||||
{
|
||||
VERIFY(is_int_type<T>());
|
||||
return static_cast<T>(m_as_int);
|
||||
VERIFY(has_u16());
|
||||
return get<int>();
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE int to_int() const
|
||||
{
|
||||
if (is_int())
|
||||
return as_int();
|
||||
return static_cast<int>(as_float());
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE float as_float() const
|
||||
{
|
||||
VERIFY(is_float());
|
||||
return m_as_float;
|
||||
if (has<int>())
|
||||
return get<int>();
|
||||
return static_cast<int>(get<float>());
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE float to_float() const
|
||||
{
|
||||
if (is_float())
|
||||
return as_float();
|
||||
return static_cast<float>(as_int());
|
||||
if (has<float>())
|
||||
return get<float>();
|
||||
return static_cast<float>(get<int>());
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE u32 as_ref_index() const
|
||||
{
|
||||
VERIFY(is_ref());
|
||||
return m_as_ref.as_ref_index();
|
||||
return get<Reference>().as_ref_index();
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE u32 as_ref_generation_index() const
|
||||
{
|
||||
VERIFY(is_ref());
|
||||
return m_as_ref.as_ref_generation_index();
|
||||
return get<Reference>().as_ref_generation_index();
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE NonnullRefPtr<Object> as_object() const { return *m_as_object; }
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE explicit operator bool() const { return !is_empty(); }
|
||||
|
||||
[[nodiscard]] String to_string(int indent = 0) const;
|
||||
|
||||
private:
|
||||
enum class Type {
|
||||
Empty,
|
||||
Null,
|
||||
Bool,
|
||||
Int,
|
||||
Float,
|
||||
Ref,
|
||||
Object,
|
||||
};
|
||||
|
||||
union {
|
||||
bool m_as_bool;
|
||||
int m_as_int;
|
||||
Reference m_as_ref;
|
||||
float m_as_float;
|
||||
};
|
||||
|
||||
RefPtr<Object> m_as_object;
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue