#pragma once #ifndef META_RUNTIME_REFLECTION_H #define META_RUNTIME_REFLECTION_H #include "any.h" #include "apply.h" #include #include #include #include #include #include namespace meta { namespace reflection { namespace detail { inline std::string RemoveTypeSpace(const std::string &str, const std::string &chars = "[]()<>*&:") { std::string result; // trim { result = str.substr(str.find_first_not_of(' ')); result = result.substr(0, result.find_last_not_of(' ') + 1); } // remove right space for (size_t i = 0; i < result.size();) { if (result[i] == ' ') { bool left_is_chars = i > 0 && chars.find(result[i - 1]) != std::string::npos; bool right_is_chars = (i + 1 < str.size()) && chars.find(result[i + 1]) != std::string::npos; if (left_is_chars || right_is_chars) { result.erase(i, 1); } else { ++i; } } else { ++i; } } return result; } template::type> std::string PrettyNameImpl() { const std::string name = typeid(U).name(); std::string pretty_name = name; int status = -4; char *res = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status); if (status == 0) { pretty_name = std::string(res); } free(res); return RemoveTypeSpace(pretty_name); } }// namespace detail template inline const std::string & PrettyName() { static std::string pretty_name = detail::PrettyNameImpl(); return pretty_name; } #if defined(__REFLECTION_PARSER__) #define META(...) __attribute__((annotate(#__VA_ARGS__))) #define CLASS(class_name, ...) class __attribute__((annotate(#__VA_ARGS__))) class_name #define STRUCT(struct_name, ...) struct __attribute__((annotate(#__VA_ARGS__))) struct_name #else #define META(...) #define CLASS(class_name, ...) class class_name #define STRUCT(struct_name, ...) struct struct_name #endif// __REFLECTION_PARSER_ #define META_REFLECTION_BODY(class_name) \ friend class meta::reflection::##class_name##_Method; \ friend class meta::reflection::##class_name##_Field; \ friend class meta::reflection::##class_name##_Constructor; \ friend class meta::reflection::##class_name##_Serializer; class Constructor; class Method; class Field; class Class; class BaseType { public: BaseType(const std::string &name, std::shared_ptr parent) : name_(name), parent_(parent) {} virtual ~BaseType() = default; std::string Name() const { return name_; } std::shared_ptr Parent() const { return parent_; } private: const std::string name_; std::shared_ptr parent_; }; class Method : public BaseType { public: Method(const std::string &name, std::shared_ptr parent) : BaseType(name, parent) {} ~Method() override = default; std::shared_ptr Parent() const { return parent_; } template::value, ReturnT>::type * = nullptr, typename... Params> inline ReturnT InvokeAndCast(void *instance, Params &&...params) const { return ::meta::reflection::any_cast(InvokeImpl(instance, {¶ms...})); } template::value, int>::type * = nullptr, typename... Params> inline void InvokeAndCast(void *instance, Params &&...params) const { ::meta::reflection::any_cast(InvokeImpl(instance, {¶ms...})); } template inline ::meta::reflection::any Invoke(void *instance, Params &&...params) const { return InvokeImpl(instance, {¶ms...}); } protected: virtual ::meta::reflection::any InvokeImpl(void *instance, const std::vector ¶ms) const = 0; private: std::shared_ptr parent_; }; class Field : public BaseType { public: Field(const std::string &name, std::shared_ptr parent) : BaseType(name, parent) {} template::value, T>::type * = nullptr> inline T GetAndCast(void *instance) const { return ::meta::reflection::any_cast(GetImpl(instance)); } ::meta::reflection::any Get(void *instance) const { return GetImpl(instance); } template inline void Set(void *instance, const T &value) const { SetImpl(instance, ::meta::reflection::any(value)); } protected: virtual ::meta::reflection::any GetImpl(void *instance) const = 0; virtual void SetImpl(void *instance, const ::meta::reflection::any &value) const = 0; }; class Class : public BaseType { public: Class(const std::string &name, std::shared_ptr base_class = nullptr) : BaseType(name, base_class) {} }; #define REFLECTION_BODY() \ friend class meta::Serializer; \ friend class meta::Class; \ friend class meta::Method; \ friend class meta::Field; \ friend class meta::Constructor; class Reflectioin { public: static Reflectioin *Instance(); ~Reflectioin(); std::shared_ptr GetClass(); // std::shared_ptr GetConstructor(std::shared_ptr clz); std::shared_ptr GetMethod(std::shared_ptr clz); std::shared_ptr GetField(std::shared_ptr clz); }; }// namespace reflection }// namespace meta #endif// META_RUNTIME_REFLECTION_H