#pragma once #include #include #include #include #include using UID = std::size_t; constexpr UID UID_INVALID = std::numeric_limits::max(); class TargetType { public: struct Field { static constexpr std::size_t FLAG_DANGEROUS = 1; std::size_t offset; std::size_t size; std::size_t flags; }; private: static constexpr std::size_t FLAG_MAIN_VARIANT = 1; static constexpr std::size_t FLAG_FIELDS = 2; UID m_uid; std::size_t m_flags; tree m_main_variant; // Fields are identified by their offsets std::map m_fields; public: TargetType(const TargetType& other) = default; TargetType& operator=(const TargetType& other) = default; TargetType(TargetType&& other) = default; TargetType& operator=(TargetType&& other) = default; TargetType(tree t); // Does NOT fetch fields ~TargetType(); bool valid() const; bool fields() const; std::string name() const; const Field* field(std::size_t off, bool exact = true) const; static void add(tree t); static std::size_t count(); static const TargetType* find(tree t); // O(n) static const TargetType* find(UID uid); // O(1) private: friend void on_finish_type(void*, void*); bool fetch_fields(bool redo = false); static TargetType* find_mutable(tree t); }; void on_register_attributes(void* plugin_data, void* user_data); void on_finish_type(void* plugin_data, void* user_data); void on_preserve_component_ref(void* plugin_data, void* user_data);