🚀 C++ RTTI反射系统深度设计文档

🌌 核心架构图

架构说明:

Object基类:所有反射类的共同基类,提供GetType()接口RTTI系统:核心反射引擎,管理类型元数据类型注册表:全局类名字典,支持动态创建和类型查找字段元数据:存储字段类型、偏移量和访问方法

🔄 类型注册流程

注册流程关键点:

类注册:RTTI_S宏创建内部RTTI类并初始化元数据字段注册:RTTI_FIELD计算字段偏移量并推导类型完成注册:RTTI_E宏结束注册过程

🧠 内存布局与访问原理

🧩 关键代码实现:

// 基于偏移量的内存访问

template

TValue& RTTI::Field::GetValue(Object* obj) noexcept {

return *(TValue*)((char*)obj + Offset);

}

// 偏移量计算宏

#define RTTI_OFFSET_OF(class, field) \

(reinterpret_cast(&reinterpret_cast( \

reinterpret_cast(0)->field)))

内存访问原理:

偏移量计算:在注册时计算字段在类中的内存偏移直接内存访问:通过对象指针 + 偏移量直接访问字段内存零开销:无虚函数调用,无中间层,直接操作内存

🔍 类型推导系统

🧬 类型推导核心代码:

template

struct TypeTraits {

static constexpr bool IsContainer = false;

static constexpr bool IsPointer = false;

// ... 其他类型特征

};

// 容器类型特化

template

struct TypeTraits> {

static constexpr bool IsContainer = true;

using ElementType = T;

static constexpr ListType ContainerType = ListType_kVector;

};

// 智能指针特化

template

struct TypeTraits> {

static constexpr bool IsPointer = true;

using PointeeType = T;

static constexpr ReferenceType PtrType = ReferenceType_kSharedPointer;

};

// 类型推导入口

template

Field CreateField(const std::string& name, size_t offset) {

if constexpr (TypeTraits::IsContainer) {

using Element = typename TypeTraits::ElementType;

Field field(name, offset, FieldType::Container);

field.ElementType = CreateField("", 0);

return field;

}

else if constexpr (TypeTraits::IsPointer) {

using Pointee = typename TypeTraits::PointeeType;

Field field(name, offset, FieldType::Reference);

field.PointeeType = CreateField("", 0);

return field;

}

// ... 其他类型处理

}

类型推导特点:

编译期推导:使用模板特化和constexpr在编译期完成类型分析递归处理:支持嵌套类型如vector>类型特征萃取:通过TypeTraits提取类型特征信息

📦 容器操作原理

🧪 容器访问示例:

// 获取容器元素指针

void* RTTI::Field::GetElementPointer(Object* obj, int index) {

switch (ContainerType) {

case ListType_kVector:

auto& vec = *reinterpret_cast*>(

(char*)obj + Offset);

return vec.data() + index * ElementType.Size;

case ListType_kQueue:

auto& que = *reinterpret_cast*>(

(char*)obj + Offset);

// 特殊处理队列访问

return AccessQueueElement(que, index);

// 其他容器类型处理

}

}

// 修改vector元素

template

bool RTTI::Field::SetValue(Object* obj, int index, const TValue& value) {

if (ListType == ListType_kVector) {

auto& vec = GetValue>(obj);

if (index >= 0 && index < vec.size()) {

vec[index] = value;

return true;

}

}

return false; // 边界检查失败

}

容器操作关键:

类型安全访问:通过模板确保类型正确性边界检查:防止越界访问零拷贝:直接操作容器内存,避免不必要的拷贝

🧲 智能指针支持

🔌 智能指针操作:

// 获取智能指针指向的对象

template

T* RTTI::Field::GetPointedObject(Object* obj) {

if (ReferenceType == ReferenceType_kSharedPointer) {

auto& ptr = GetValue>(obj);

return ptr.get();

}

else if (ReferenceType == ReferenceType_kUniquePointer) {

auto& ptr = GetValue>(obj);

return ptr.get();

}

return nullptr;

}

// 重置智能指针

template

void RTTI::Field::ResetPointer(Object* obj, T* newPtr) {

if (ReferenceType == ReferenceType_kSharedPointer) {

auto& ptr = GetValue>(obj);

ptr.reset(newPtr);

}

else if (ReferenceType == ReferenceType_kUniquePointer) {

auto& ptr = GetValue>(obj);

ptr.reset(newPtr);

}

}

智能指针支持特点:

安全访问:通过get()方法获取原始指针,避免直接暴露生命周期管理:支持reset等操作管理对象生命周期空指针检测:自动处理空指针情况

⚙️ 宏系统实现原理

🔬 宏展开示例:

// 原始代码

RTTI_S(GameObject)

RTTI_FIELD(position)

RTTI_E

// 展开后

class __RTTI__GameObject : public RTTI {

public:

static __RTTI__GameObject r;

__RTTI__GameObject() {

GlobalRegistry::Register(

"GameObject",

[]{ return new GameObject(); },

this

);

// 注册字段

RegisterField("position",

offsetof(GameObject, position),

TypeTraits::GetTypeInfo()

);

}

};

__RTTI__GameObject __RTTI__GameObject::r;

// 在GameObject类中添加

virtual RTTI* GetType() const override {

return &__RTTI__GameObject::r;

}

宏系统优势:

简化注册:用户只需简单宏调用即可完成复杂注册自动生成代码:在预处理阶段生成必要的RTTI代码隔离复杂性:用户无需了解底层实现细节

⚡ 性能优化设计

性能优化措施:

内存访问优化:

// 直接内存访问,无函数调用开销

#define DIRECT_ACCESS(ptr, offset) \

(*reinterpret_cast*>( \

reinterpret_cast(ptr) + offset))

编译期类型解析:

template

constexpr FieldType DeduceFieldType() {

if constexpr (std::is_integral_v) return FieldType::Int;

else if constexpr (std::is_floating_point_v) return FieldType::Float;

// ... 其他类型

}

快速注册表查找:

class GlobalRegistry {

private:

static std::unordered_map typeMap;

static std::unordered_map creatorMap;

public:

template

static void Register(const std::string& name) {

typeMap[name] = T::GetStaticType();

creatorMap[name] = []{ return new T(); };

}

};

🧪 完整操作示例

典型使用场景:

// 动态创建对象

GameObject* obj = RTTI::New("GameObject");

// 获取类型信息

RTTI* type = obj->GetType();

// 遍历所有字段

for (auto& field : type->GetFields()) {

std::cout << "Field: " << field.Name

<< " Type: " << field.TypeName();

}

// 修改字段值

if (auto* posField = type->GetField("position")) {

Vector3 newPos(10, 20, 30);

posField->SetValue(obj, newPos);

}

🔧 框架扩展机制

🧩 扩展示例:

// 添加自定义容器支持

template

struct is_custom_container : std::false_type {};

template

struct is_custom_container> : std::true_type {};

// 在类型推导中添加处理分支

template

Field CreateField(const std::string& name, size_t offset) {

if constexpr (is_custom_container::value) {

Field field(name, offset, FieldType::CustomContainer);

// 实现自定义访问方法

field.GetElement = [](void* container, int index) {

return &static_cast*>(container)

->GetElement(index);

};

return field;

}

// ... 其他类型

}

// 序列化扩展

void Serialize(Object* obj, std::ostream& out) {

RTTI* type = obj->GetType();

for (auto& field : type->GetFields()) {

out << field.Name << ": ";

if (field.IsBasicType()) {

// 基础类型序列化

}

else if (field.IsContainer()) {

// 容器序列化

}

}

}

扩展能力:

新容器支持:通过模板特化添加新容器类型序列化:基于反射自动序列化/反序列化脚本绑定:自动生成脚本语言绑定代码编辑器集成:自动生成属性面板

📊 类型系统总览

详细类型支持矩阵

类型类别具体类型C++示例RTTI表示基础类型整数int, int32_tBasicType_kInt浮点数float, doubleBasicType_kFloat字符串std::stringBasicType_kString布尔boolBasicType_kBoolean容器类型动态数组std::vectorListType_kVector队列std::queueListType_kQueue静态数组std::arrayListType_kStatic集合std::setListType_kSet指针类型原始指针GameObject*ReferenceType_kPointer共享指针std::shared_ptrReferenceType_kSharedPointer唯一指针std::unique_ptrReferenceType_kUniquePointer值类型自定义类Vector3FieldType_Custom

🏆 框架优势总结

高性能设计:

直接内存访问(零抽象开销)编译期类型解析(零运行时成本)哈希表快速查找(O(1)复杂度)

强大类型支持:

// 支持复杂嵌套类型

class Scene {

std::vector> objects;

std::map> colorPalette;

RTTI_FIELD(objects);

RTTI_FIELD(colorPalette);

};

安全保证:

类型安全访问容器边界检查空指针检测

可扩展架构:

// 轻松添加新功能

RTTI_REGISTER_EXTENSION(Serialization, {

// 序列化实现

});

🧩 RTTI 轻量框架运行库实现

DEMO:

#include "RTTI.h"

#include "Object.h"

struct Vector3 : public Object {

float x, y, z;

Vector3(float x = 0, float y = 0, float z = 0) : x(x), y(y), z(z) {}

RTTI_S(Vector3);

RTTI_FIELD(x);

RTTI_FIELD(y);

RTTI_FIELD(z);

RTTI_E;

};

struct GameObject : public Object {

std::string name;

Vector3 position;

std::shared_ptr child;

std::vector scores;

std::queue messages;

GameObject() {

scores = { 90, 85, 95 };

messages.push("Hello");

messages.push("World");

}

RTTI_S(GameObject);

RTTI_FIELD(name);

RTTI_FIELD(position);

RTTI_FIELD(child);

RTTI_FIELD(scores);

RTTI_FIELD(messages);

RTTI_E;

};

static void InitMetadata() {

RTTI_I(Vector3);

RTTI_I(GameObject);

}

std::string GetTypeName(const RTTI::Field* field) {

// 优先处理容器元素类型

if (field->ListType != RTTI::ListType_kNull && field->Type) {

return field->Type->GetName();

}

// 处理引用类型

if (field->ReferenceType != RTTI::ReferenceType_kNull && field->Type) {

return field->Type->GetName();

}

// 基本类型处理

switch (field->BaiscType) {

case RTTI::BasicType_kInt: return "int";

case RTTI::BasicType_kUInt: return "uint";

case RTTI::BasicType_kFloat: return "float";

case RTTI::BasicType_kString: return "string";

case RTTI::BasicType_kClass:

return field->Type ? field->Type->GetName() : "unknown_class";

default: return "unknown";

}

}

void PrintFieldInfo(RTTI::Field* field) {

std::cout << " " << field->Name << " [";

// 打印容器类型

if (field->ListType != RTTI::ListType_kNull) {

switch (field->ListType) {

case RTTI::ListType_kVector: std::cout << "vector<"; break;

case RTTI::ListType_kQueue: std::cout << "queue<"; break;

case RTTI::ListType_kStatic: std::cout << "array<"; break;

default: std::cout << "container<";

}

std::cout << GetTypeName(field);

std::cout << ">";

if (field->ListType == RTTI::ListType_kStatic) {

std::cout << ", size=" << field->ArraySize;

}

}

// 打印引用类型

else if (field->ReferenceType != RTTI::ReferenceType_kNull) {

switch (field->ReferenceType) {

case RTTI::ReferenceType_kSharedPointer:

std::cout << "shared_ptr<"; break;

case RTTI::ReferenceType_kUniquePointer:

std::cout << "unique_ptr<"; break;

default: std::cout << "ref<";

}

std::cout << GetTypeName(field) << ">";

}

// 打印基本类型

else {

std::cout << GetTypeName(field);

}

std::cout << "]\n";

}

int main() {

InitMetadata();

// 动态创建对象

GameObject* obj = (GameObject*)RTTI::New("GameObject");

obj->name = "Player1";

// 获取类型信息

RTTI* type = obj->GetType();

std::cout << "Type: " << type->GetName() << "\n";

// 遍历所有字段

std::cout << "\nFields Info:\n";

for (auto& [name, field] : type->GetAllFields()) {

PrintFieldInfo(const_cast(&field));

}

// 反射访问基本类型

RTTI::Field* nameField = type->GetField("name");

std::string nameValue = nameField->GetValue(obj);

std::cout << "\nName: " << nameValue << "\n";

// 反射访问嵌套对象

RTTI::Field* posField = type->GetField("position");

Vector3& pos = posField->GetValue(obj);

std::cout << "Position: (" << pos.x << ", " << pos.y << ", " << pos.z << ")\n";

// 修改容器字段 - vector

RTTI::Field* scoresField = type->GetField("scores");

scoresField->SetValue(obj, 1, 100); // 修改第二个元素

// 访问容器字段 - queue

RTTI::Field* msgField = type->GetField("messages");

std::string* lastMsg = nullptr;

if (msgField->GetLastValuePointer(obj, &lastMsg)) {

*lastMsg = "Modified!"; // 修改队列尾部

std::cout << "Last message: " << *lastMsg << "\n";

}

// 反射创建智能指针对象

RTTI::Field* childField = type->GetField("child");

GameObject* childObj = (GameObject*)RTTI::New("GameObject");

childObj->name = "Child";

childField->SetValue2(obj, std::shared_ptr(childObj));

// 获取智能指针字段

std::shared_ptr& childRef =

childField->GetValue>(obj);

std::cout << "Child name: " << childRef->name << "\n";

delete obj;

return 0;

}

Object.h:

#pragma once

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#ifndef offset_of

#define offset_of(type, member) ((size_t)&reinterpret_cast((((type*)0)->member)))

#endif

#ifndef container_of

#define container_of(ptr, type, member) ((type*)((char*)static_castmember)*>(ptr) - offset_of(type, member)))

#endif

#ifndef type_of

#define type_of(type) (type::TypeOf())

#endif

class Object {

friend class RTTI;

public:

virtual RTTI* GetType() noexcept = 0;

virtual int GetHashCode() noexcept {

return (int)std::hash()(reinterpret_cast(this));

}

};

template

constexpr T& constant_of(const T& v) noexcept {

return const_cast(v);

}

RTTI.h:

#pragma once

#include "Object.h"

#define RTTI_S(clazz) \

public: static std::string GetClassName() noexcept { return #clazz; } \

private: class __RTTI__ : public RTTI { \

typedef clazz _Ty; \

public: \

static __RTTI__& c() noexcept { \

static __RTTI__ r; \

return r; \

} \

virtual std::string GetName() const noexcept override { return #clazz; } \

__RTTI__() noexcept { \

__rtti_ptrs[#clazz] = this; \

__rtti_news[#clazz] = []() noexcept -> Object* { return new clazz(); }; \

#define RTTI_E \

} \

}; \

public: static RTTI* TypeOf() noexcept { return &__RTTI__::c(); } \

public: virtual RTTI* GetType() noexcept override { return &__RTTI__::c(); }

#define RTTI_FIELD(var) \

__rtti_fields[#var] = __RTTI_IMPL__::__RTTI_IMPL_FIELD_CLASS__::RTTI_GetField_0var)>::type>(#var, offset_of(_Ty, var));

#define RTTI_I(clazz) type_of(clazz);

class Object;

class RTTI {

protected:

typedef Object* (*NewObjectFx)();

static std::unordered_map __rtti_news;

static std::unordered_map __rtti_ptrs;

public:

enum kBasicType {

BasicType_kClass,

BasicType_kString,

BasicType_kChar,

BasicType_kSByte,

BasicType_kByte,

BasicType_kShort,

BasicType_kUShort,

BasicType_kInt,

BasicType_kUInt,

BasicType_kLong,

BasicType_kULong,

BasicType_kBoolean,

BasicType_kFloat,

BasicType_kDouble,

BasicType_kDecimal,

};

enum kReferenceType {

ReferenceType_kNull,

ReferenceType_kPointer,

ReferenceType_kReference,

ReferenceType_kWeakPointer,

ReferenceType_kUniquePointer,

ReferenceType_kSharedPointer,

};

enum kListType {

ListType_kNull,

ListType_kArray,

ListType_kList,

ListType_kVector,

ListType_kStack,

ListType_kQueue,

ListType_kStatic,

ListType_kSet,

ListType_kMultiSet,

};

class Field final {

public:

const std::string Name;

const int Offset = 0;

const RTTI* Type = NULL;

const bool Constant = false;

const kBasicType BaiscType = BasicType_kClass;

const kReferenceType ReferenceType = ReferenceType_kNull;

const kListType ListType = ListType_kNull;

const int SizeOf = 0;

const int ArraySize = 0;

public:

const Field& operator=(const Field& reft) const noexcept {

Field& left = const_cast(*this);

constant_of(left.Name) = reft.Name;

constant_of(left.Offset) = reft.Offset;

constant_of(left.Type) = reft.Type;

constant_of(left.Constant) = reft.Constant;

constant_of(left.BaiscType) = reft.BaiscType;

constant_of(left.ListType) = reft.ListType;

constant_of(left.SizeOf) = reft.SizeOf;

constant_of(left.ArraySize) = reft.ArraySize;

constant_of(left.ReferenceType) = reft.ReferenceType;

return left;

}

template

TValue& GetValue(Object* obj) noexcept;

template

bool GetValue(Object* obj, int index, TValue& out) noexcept;

template

bool SetValue(Object* obj, int index, const TValue& value) noexcept;

template

bool GetValuePointer(Object* obj, int index, TValue** out) noexcept;

template

TValue& SetValue(Object* obj, const TValue& value) noexcept;

template

TValue& SetValue2(Object* obj, TValue&& value) noexcept;

template

bool GetFirstValuePointer(Object* obj, TValue** out) noexcept;

template

bool GetLastValuePointer(Object* obj, TValue** out) noexcept;

template

bool GetFirstValue(Object* obj, TValue& out) noexcept;

template

bool GetLastValue(Object* obj, TValue& out) noexcept;

private:

template

bool GetFirstValuePointer2(Object* obj, TValue** out) noexcept;

template

bool GetLastValuePointer2(Object* obj, TValue** out) noexcept;

};

Field* GetField(const std::string& method) noexcept;

const std::unordered_map& GetAllFields() noexcept { return __rtti_fields; }

virtual std::string GetName() const noexcept = 0;

static RTTI* GetType(const std::string& class_name) noexcept;

Object* New() noexcept;

static Object* New(const std::string& class_name) noexcept;

protected:

std::unordered_map __rtti_fields;

};

namespace __RTTI_IMPL__ {

class __RTTI_IMPL_FIELD_CLASS__{

template

struct HAS_MEMBER_TYPE_OF_FUNCTION final {

private:

template

static auto SFINAE_TEST(T*) noexcept -> decltype(std::declval().GetType(), std::true_type());

template

static std::false_type SFINAE_TEST(...) noexcept;

public:

static constexpr bool value = decltype(SFINAE_TEST(NULL))::value;

};

template

struct is_shared_ptr : std::false_type {};

template

struct is_shared_ptr> : std::true_type {};

template

struct is_weak_ptr : std::false_type {};

template

struct is_weak_ptr> : std::true_type {};

template

struct is_unique_ptr : std::false_type {};

template

struct is_unique_ptr> : std::true_type {};

template

struct is_vector : std::false_type {};

template

struct is_vector> : std::true_type {};

template

struct is_list : std::false_type {};

template

struct is_list> : std::true_type {};

template

struct is_stack : std::false_type {};

template

struct is_stack> : std::true_type {};

template

struct is_queue : std::false_type {};

template

struct is_queue> : std::true_type {};

template

struct is_set : std::false_type {};

template

struct is_set> : std::true_type {};

template

struct is_multiset : std::false_type {};

template

struct is_multiset> : std::true_type {};

template

struct is_array : std::false_type {};

template

struct is_array> : std::true_type {

typedef T type;

static constexpr std::size_t length = N;

};

template

struct is_static_array : std::false_type {};

template

struct is_static_array : std::true_type {

static constexpr std::size_t length = N;

};

public:

template

static RTTI* RTTI_GetType() noexcept {

if constexpr (std::is_base_of::value && HAS_MEMBER_TYPE_OF_FUNCTION<_Ty>::value) {

RTTI* type = RTTI::GetType(_Ty::GetClassName());

if (NULL != type) {

return type;

}

return _Ty::TypeOf();

}

else {

return NULL;

}

}

template

static RTTI::Field RTTI_GetField_0(const std::string& name, int offset) noexcept {

using _Ty2 = typename std::remove_const<_Ty>::type;

return RTTI_GetField_1<_Ty2>(name, offset, std::is_const<_Ty>::value);

}

template

static RTTI::Field RTTI_GetField_1(const std::string& name, int offset, bool constant) noexcept {

if constexpr (is_vector<_Ty>::value) {

using _Ty2 = typename std::remove_referencebegin())>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kVector);

}

else if constexpr (is_static_array<_Ty>::value) { /* std::is_array<_Ty>::value */

using _Ty2 = typename std::remove_reference::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kStatic, is_static_array<_Ty>::length);

}

else if constexpr (is_array<_Ty>::value) {

using _Ty2 = typename std::remove_reference::type>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kArray, is_array<_Ty>::length);

}

else if constexpr (is_list<_Ty>::value) {

using _Ty2 = typename std::remove_referencebegin())>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kList);

}

else if constexpr (is_set<_Ty>::value) {

using _Ty2 = typename std::remove_referencebegin())>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kSet);

}

else if constexpr (is_multiset<_Ty>::value) {

using _Ty2 = typename std::remove_referencebegin())>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kMultiSet);

}

else if constexpr (is_stack<_Ty>::value) {

using _Ty1 = decltype(((_Ty*)0)->top());

using _Ty2 = typename std::remove_const::type>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kStack);

}

else if constexpr (is_queue<_Ty>::value) {

using _Ty1 = decltype(((_Ty*)0)->front());

using _Ty2 = typename std::remove_const::type>::type;

return RTTI_GetField_2<_Ty2>(name, offset, constant, RTTI::ListType_kQueue);

}

else {

return RTTI_GetField_2<_Ty>(name, offset, constant, RTTI::ListType_kNull);

}

}

template

static RTTI::Field RTTI_GetField_2(const std::string& name, int offset, bool constant, RTTI::kListType list_type, int array_size = 0) noexcept {

RTTI::Field field{ name, offset, NULL, constant, RTTI::BasicType_kClass, RTTI::ReferenceType_kNull, list_type, sizeof(_Ty), array_size };

RTTI::kBasicType& basic_type = constant_of(field.BaiscType);

if constexpr (std::is_same<_Ty, int32_t>::value || std::is_same<_Ty, int>::value || std::is_same<_Ty, long>::value) {

basic_type = RTTI::BasicType_kInt;

}

else if constexpr (std::is_same<_Ty, uint32_t>::value || std::is_same<_Ty, unsigned int>::value || std::is_same<_Ty, unsigned long>::value) {

basic_type = RTTI::BasicType_kUInt;

}

else if constexpr (std::is_same<_Ty, int64_t>::value || std::is_same<_Ty, long long>::value || std::is_same<_Ty, long long int>::value) {

basic_type = RTTI::BasicType_kLong;

}

else if constexpr (std::is_same<_Ty, uint64_t>::value || std::is_same<_Ty, unsigned long long>::value || std::is_same<_Ty, unsigned long long int>::value) {

basic_type = RTTI::BasicType_kULong;

}

else if constexpr (std::is_same<_Ty, double>::value || std::is_same<_Ty, double_t>::value) {

basic_type = RTTI::BasicType_kDouble;

}

else if constexpr (std::is_same<_Ty, long double>::value) {

basic_type = RTTI::BasicType_kDecimal;

}

else if constexpr (std::is_same<_Ty, bool>::value) {

basic_type = RTTI::BasicType_kBoolean;

}

else if constexpr (std::is_same<_Ty, short>::value || std::is_same<_Ty, int16_t>::value) {

basic_type = RTTI::BasicType_kSort;

}

else if constexpr (std::is_same<_Ty, unsigned short>::value || std::is_same<_Ty, uint16_t>::value) {

basic_type = RTTI::BasicType_kUSort;

}

else if constexpr (std::is_same<_Ty, int8_t>::value) {

basic_type = RTTI::BasicType_kSByte;

}

else if constexpr (std::is_same<_Ty, uint8_t>::value) {

basic_type = RTTI::BasicType_kByte;

}

else if constexpr (std::is_same<_Ty, char>::value) {

basic_type = RTTI::BasicType_kChar;

}

else if constexpr (std::is_same<_Ty, std::string>::value) {

basic_type = RTTI::BasicType_kString;

}

else if constexpr (std::is_pointer<_Ty>::value) {

using _Ty2 = typename std::remove_pointer<_Ty>::type;

constant_of(field.ReferenceType) = RTTI::ReferenceType_kPointer;

constant_of(field.Type) = RTTI_GetType<_Ty2>();

constant_of(field.SizeOf) = sizeof(_Ty2);

}

else if constexpr (is_weak_ptr<_Ty>::value) {

using _Ty2 = typename std::remove_pointer;

constant_of(field.ReferenceType) = RTTI::ReferenceType_kWeakPointer;

constant_of(field.Type) = RTTI_GetType<_Ty2>();

constant_of(field.SizeOf) = sizeof(_Ty2);

}

else if constexpr (is_shared_ptr<_Ty>::value) {

using _Ty2 = typename std::remove_pointerget())>::type;

constant_of(field.ReferenceType) = RTTI::ReferenceType_kSharedPointer;

constant_of(field.Type) = RTTI_GetType<_Ty2>();

constant_of(field.SizeOf) = sizeof(_Ty2);

}

else if constexpr (is_unique_ptr<_Ty>::value) {

using _Ty2 = typename std::remove_pointerget())>::type;

constant_of(field.ReferenceType) = RTTI::ReferenceType_kUniquePointer;

constant_of(field.Type) = RTTI_GetType<_Ty2>();

constant_of(field.SizeOf) = sizeof(_Ty2);

}

else if constexpr (std::is_reference<_Ty>::value) {

using _Ty2 = typename std::remove_reference<_Ty>::type;

constant_of(field.ReferenceType) = RTTI::ReferenceType_kReference;

constant_of(field.Type) = RTTI_GetType<_Ty2>();

constant_of(field.SizeOf) = sizeof(_Ty2);

}

else {

constant_of(field.Type) = RTTI_GetType<_Ty>();

}

return field;

}

};

}

template

TValue& RTTI::Field::GetValue(Object* obj) noexcept {

return *(TValue*)((char*)obj + Offset);

}

template

TValue& RTTI::Field::SetValue(Object* obj, const TValue& value) noexcept {

TValue& data = *(TValue*)((char*)obj + Offset);

data = value;

return data;

}

template

TValue& RTTI::Field::SetValue2(Object* obj, TValue&& value) noexcept {

TValue& data = *(TValue*)((char*)obj + Offset);

data = value;

return data;

}

template

bool RTTI::Field::GetValue(Object* obj, int index, TValue& out) noexcept {

TValue* ppv{ NULL };

if (!GetValuePointer(obj, index, &ppv)) {

return false;

}

out = *ppv;

return true;

}

template

bool RTTI::Field::GetValuePointer(Object* obj, int index, TValue** out) noexcept {

if (NULL == out || index < 0) {

return false;

}

else if (ListType == ListType_kStatic || ListType == ListType_kArray) {

if (index >= ArraySize) {

return false;

}

TValue& data_ref = GetValue(obj);

TValue* data_ptr = std::addressof(data_ref);

*out = data_ptr + index;

return true;

}

else if (ListType == ListType_kVector) {

using _Ty2 = std::vector;

_Ty2& vc = GetValue<_Ty2>(obj);

if (index >= (int)vc.size()) {

return false;

}

*out = vc.data() + index;

return true;

}

else {

return false;

}

}

template

bool RTTI::Field::SetValue(Object* obj, int index, const TValue& value) noexcept {

TValue* ppv{ NULL };

if (!GetValuePointer(obj, index, &ppv)) {

return false;

}

*ppv = value;

return true;

}

template

bool RTTI::Field::GetFirstValuePointer2(Object* obj, TValue** out) noexcept {

TList& list = GetValue(obj);

auto tail = list.begin();

auto endl = list.end();

if (tail == endl) {

return false;

}

auto& ref = *tail;

*out = (TValue*)std::addressof(ref);

return true;

}

template

bool RTTI::Field::GetLastValuePointer2(Object* obj, TValue** out) noexcept {

TList& list = GetValue(obj);

auto tail = list.rbegin();

auto endl = list.rend();

if (tail == endl) {

return false;

}

auto& ref = *tail;

*out = (TValue*)std::addressof(ref);

return true;

}

template

bool RTTI::Field::GetFirstValuePointer(Object* obj, TValue** out) noexcept {

if (NULL == out) {

return false;

}

else if (ListType == ListType_kStatic || ListType == ListType_kArray) {

if (ArraySize < 1) {

return false;

}

TValue& data_ref = GetValue(obj);

*out = std::addressof(data_ref);

return true;

}

else if (ListType == ListType_kVector) {

using _Ty2 = std::vector;

_Ty2& vc = GetValue<_Ty2>(obj);

if (vc.empty()) {

return false;

}

*out = vc.data();

return true;

}

else if (ListType == ListType_kList) {

using _Ty2 = std::list;

return GetFirstValuePointer2<_Ty2>(obj, out);

}

else if (ListType == ListType_kSet) {

using _Ty2 = std::set;

return GetFirstValuePointer2<_Ty2>(obj, out);

}

else if (ListType == ListType_kMultiSet) {

using _Ty2 = std::multiset;

return GetFirstValuePointer2<_Ty2>(obj, out);

}

else if (ListType == ListType_kStack) {

using _Ty2 = std::stack;

_Ty2& stack = GetValue<_Ty2>(obj);

if (stack.empty()) {

return false;

}

*out = std::addressof(stack.top());

return true;

}

else if (ListType == ListType_kQueue) {

using _Ty2 = std::queue;

_Ty2& queue = GetValue<_Ty2>(obj);

if (queue.empty()) {

return false;

}

*out = std::addressof(queue.front());

return true;

}

else {

return false;

}

}

template

bool RTTI::Field::GetLastValuePointer(Object* obj, TValue** out) noexcept {

if (NULL == out) {

return false;

}

else if (ListType == ListType_kStatic || ListType == ListType_kArray) {

if (ArraySize < 1) {

return false;

}

TValue& data_ref = GetValue(obj);

*out = std::addressof(data_ref) + (ArraySize - 1);

return true;

}

else if (ListType == ListType_kVector) {

using _Ty2 = std::vector;

_Ty2& vc = GetValue<_Ty2>(obj);

if (vc.empty()) {

return false;

}

*out = std::addressof(*vc.rbegin());

return true;

}

else if (ListType == ListType_kList) {

using _Ty2 = std::list;

return GetLastValuePointer2<_Ty2>(obj, out);

}

else if (ListType == ListType_kSet) {

using _Ty2 = std::set;

return GetLastValuePointer2<_Ty2>(obj, out);

}

else if (ListType == ListType_kMultiSet) {

using _Ty2 = std::multiset;

return GetLastValuePointer2<_Ty2>(obj, out);

}

else if (ListType == ListType_kStack) {

using _Ty2 = std::stack;

_Ty2& stack = GetValue<_Ty2>(obj);

std::size_t stack_size = stack.size();

if (stack_size != 1) {

return false;

}

*out = std::addressof(stack.top());

return true;

}

else if (ListType == ListType_kQueue) {

using _Ty2 = std::queue;

_Ty2& queue = GetValue<_Ty2>(obj);

if (queue.empty()) {

return false;

}

*out = std::addressof(queue.back());

return true;

}

else {

return false;

}

}

template

bool RTTI::Field::GetFirstValue(Object* obj, TValue& out) noexcept {

TValue* ppv{ NULL };

if (!GetFirstValuePointer(obj, &ppv)) {

return false;

}

out = *ppv;

return true;

}

template

bool RTTI::Field::GetLastValue(Object* obj, TValue& out) noexcept {

TValue* ppv{ NULL };

if (!GetLastValuePointer(obj, &ppv)) {

return false;

}

out = *ppv;

return true;

}

RTTI.cpp:

#include "RTTI.h"

std::unordered_map RTTI::__rtti_news;

std::unordered_map RTTI::__rtti_ptrs;

Object* RTTI::New(const std::string& class_name) noexcept {

if (class_name.empty()) {

return NULL;

}

auto tail = __rtti_news.find(class_name);

auto endl = __rtti_news.end();

if (tail == endl) {

return NULL;

}

NewObjectFx f = tail->second;

return f();

}

RTTI* RTTI::GetType(const std::string& class_name) noexcept {

if (class_name.empty()) {

return NULL;

}

auto tail = __rtti_ptrs.find(class_name);

auto endl = __rtti_ptrs.end();

if (tail == endl) {

return NULL;

}

return tail->second;

}

Object* RTTI::New() noexcept {

std::string class_name = GetName();

return New(class_name);

}

RTTI::Field* RTTI::GetField(const std::string& method) noexcept {

if (method.empty()) {

return NULL;

}

auto tail = __rtti_fields.find(method);

auto endl = __rtti_fields.end();

if (tail == endl) {

return NULL;

}

return &tail->second;

}

本反射系统通过创新的内存访问机制和编译期类型推导,在保持C++性能优势的同时提供了强大的运行时反射能力。