注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

进击の架构师

 
 
 

日志

 
 

[C/C++]构建简单的C++运行时反射类型系统  

2014-04-05 11:58:39|  分类: C/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

运行期构建C++类型系统这篇文章中,我构建了一套简单的运行期C++类型系统,当时提到了它的应用场景有字符串映射到类型,本篇文章展示的是它的简单实现。

Metadata.h

#ifndef METADATA_H
#define METADATA_H


#include <assert.h>


#include <vector>
#include <string>
using namespace std;


/*
* 成员变量的元数据
*/
struct FieldMetadata
{
// 成员变量的名称
string name;

// 成员变量的类型
string type;

// 成员变量的地址
size_t offset;

FieldMetadata(string name, string type, size_t offset)
{
this->name = name;
this->type = type;
this->offset = offset;
}
};


/*
* 声明结构体类型
*/
#define Declare_Struct(class_type) \
private: \
\
typedef class_type this_class; \
\
template<int N> class Init_I \
{ \
public: \
Init_I(vector<FieldMetadata>& metas) \
{} \
}; \


/*
* 定义结构体变量
*/
#define Define_Field(var_index, var_type, var_name) \
public: \
\
var_type var_name; \
\
private: \
\
template<> class Init_I<var_index> \
{ \
public: \
Init_I(vector<FieldMetadata>& metas) \
{ \
FieldMetadata fmd(#var_name, typeid(var_type).name(), offsetof(this_class, var_name)); \
metas.insert(metas.begin(), fmd); \
} \
}; \


/*
* 定义结构体元数据
*/
#define Define_Metadata(var_count) \
public: \
\
static vector<FieldMetadata> fieldinfo; \
\
private: \
\
template<int N> class CallInits \
{ \
public: \
CallInits(vector<FieldMetadata>& metas) \
{ \
Init_I<N> in(metas); \
CallInits<N-1> ci(metas); \
} \
}; \
\
template<> class CallInits<1> \
{ \
public: \
CallInits(vector<FieldMetadata>& metas) \
{ \
Init_I<1> in(metas); \
} \
}; \
\
static vector<FieldMetadata> Init() \
{ \
vector<FieldMetadata> fmd; \
CallInits<var_count> ci(fmd); \
return fmd; \
} \


/*
* 实现结构体类型
*/
#define Implement_Struct(class_type) \
vector<FieldMetadata> class_type::fieldinfo = class_type::Init(); \


typedef unsigned char byte;


/*
* 解析字符串到类型
*/
template<typename _T>
class ParaseToType
{
private:

/*
* 内存值拷贝
*/
void CopyValueOnMemory(byte* memvalue, string type, string strvalue)
{
int off = strvalue.find('=');
string name = strvalue.substr(0, off);
string value = strvalue.substr(off + 1);

if (type.compare(typeid(int).name()) == 0)
{
int vl = atoi(value.c_str());
memcpy(memvalue, &vl, sizeof(int));
}
else if (type.compare(typeid(double).name()) == 0)
{
double vl = atof(value.c_str());
memcpy(memvalue, &vl, sizeof(double));
}
else if (type.compare(typeid(string).name()) == 0)
{
string* strmem = (string*)memvalue;
strmem->append(value);
}
else
{
/*
* Only support the following types
* int, double, std::string
*/
assert(false);
}
}

public:

/*
* 字符串的格式:"a=5;b=6.0f;c=766666666hhhhhgfdd"
*/
bool Parase(_T& t, string strvalue)
{
int stroffset = 0;

for (auto iter = _T::fieldinfo.begin(); iter != _T::fieldinfo.end(); iter++)
{
int newoffset = strvalue.find(';', stroffset);
string ty = strvalue.substr(stroffset, newoffset - stroffset);

byte* th = (((byte*)&t) + (*iter).offset);
CopyValueOnMemory(th, (*iter).type, ty);

stroffset = newoffset + 1;
}

return true;
}

};


#endif /*METADATA_H*/

Test.h

#pragma once


#include "Metadata.h"


struct Test
{
Declare_Struct(Test)


Define_Field(1, int, a)


Define_Field(2, double, b)


Define_Field(3, string, c)


Define_Metadata(3)

};

Test.cpp

#include "Test.h"


Implement_Struct(Test)


main.cpp

#include "Test.h"
#include <assert.h>


template<typename _T> void PrintFieldInfo()
{
printf("struct size : %d \n", sizeof(_T));
printf("fieldinfo size : %d \n", _T::fieldinfo.size());
printf("struct layout : \n");
for (auto iter = _T::fieldinfo.begin(); iter != _T::fieldinfo.end(); iter++)
{
printf("%s, %s, %d \n", (*iter).name.c_str(), (*iter).type.c_str(), (*iter).offset);
}
}


void main()
{
PrintFieldInfo<Test>();

Test test;
ParaseToType<Test>().Parase(test, "a=5;b=6.0f;c=766666666hhhhhgfdd");
printf("a = %d, b = %f, c = %s \n", test.a, test.b, test.c.c_str());
}



  评论这张
 
阅读(849)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017