meta/runtime/reflection.h
2024-03-03 17:19:41 +08:00

157 lines
4.1 KiB
C++

#pragma once
#ifndef META_RUNTIME_REFLECTION_H
#define META_RUNTIME_REFLECTION_H
#include <string>
#include <type_traits>
#include <vector>
namespace meta {
#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 REFLECTION_BODY(class_name) \
friend class meta::Serializer; \
friend class meta::Class; \
friend class meta::Method; \
friend class meta::Field; \
friend class meta::Constructor;
class TypeInfo {
public:
TypeInfo(const std::string &name) : name_(name) {}
virtual ~TypeInfo() = default;
std::string name() const;
virtual bool IsStatic() const = 0;
virtual bool IsConst() const = 0;
virtual bool IsWritable() const { return !IsConst(); };
private:
const std::string name_;
};
class Class;
class Constructor;
class Field;
class Method;
class Class : public TypeInfo {
public:
Class(const std::string &name) : TypeInfo(name) {}
~Class() override = default;
Constructor GetConstructor(const std::string &name) const;
Field GetField(const std::string &name) const;
Method GetMethod(const std::string &name) const;
};
/**
* class Test {
* Test();
* Test(int val);
* Test(const Test & other);
* };
**/
class Constructor : public TypeInfo {
public:
Constructor(const std::string &name, const Class &clz) : TypeInfo(name), parent_(clz) {}
~Constructor() override = default;
template<typename... Args>
void *NewInstance(Args... args) const
{
return NewInstanceImpl({&args...});
}
protected:
virtual void *NewInstanceImpl(const std::vector<void *> &args) const = 0;
const Class &parent_;
};
class Field : public TypeInfo {
public:
Field(const std::string &name, const Class &clz) : TypeInfo(name), parent_(clz) {}
~Field() override = default;
template<typename T>
void Set(void *instance, T &&value) const
{
SetImpl(instance, &value);
}
template<typename T>
const T &Get(void *instance) const
{
return *static_cast<T *>(GetImpl(instance));
}
template<typename T>
T &Get(void *instance) const
{
return *static_cast<T *>(GetImpl(instance));
}
protected:
virtual void SetImpl(void *instance, void *value) const = 0;
virtual void *GetImpl(void *instance) const = 0;
const Class &parent_;
};
class Method : public TypeInfo {
public:
Method(const std::string &name, const Class &clz) : TypeInfo(name), parent_(clz) {}
~Method() override = default;
template<typename ReturnT,
typename std::enable_if<!std::is_void<ReturnT>::value, ReturnT>::type * = nullptr>
inline ReturnT InvokeProxy(void *instance, const std::vector<void *> &args) const
{
return *static_cast<ReturnT *>(InvokeImpl(instance, args));
}
inline void InvokeProxy(void *instance, const std::vector<void *> &args) const
{
InvokeImpl(instance, args);
}
template<typename ReturnT, typename... Args>
inline ReturnT Invoke(void *instance, Args... args)
{
return InvokeProxy<ReturnT>(instance, {&args...});
}
template<typename... Args>
inline void Invoke(void *instance, Args... args)
{
InvokeProxy<void>(instance, {&args...});
}
protected:
virtual void *InvokeImpl(void *instance, const std::vector<void *> &args) const = 0;
const Class &parent_;
};
class Reflectioin {
public:
static Reflectioin *Instance();
~Reflectioin();
};
}// namespace meta
#endif// META_RUNTIME_REFLECTION_H