栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++模板】结构体数据转换

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++模板】结构体数据转换

在这里插入代码片
#include 
#include 

template
using void_t = void;

//用于从可变字段类型列表中获取结构体相关信息
template
struct StructProperty
{
private:
	constexpr static std::size_t cur_align_size = align_size > sizeof(T) ? sizeof(T) : align_size;
	constexpr static std::size_t cur_p = StructProperty::next_p;

public:	
	constexpr static std::size_t elem_num = sizeof...(Ts) + 1;
	constexpr static std::size_t size_sum = sizeof(T) + StructProperty::size_sum;
	constexpr static std::size_t max_size = sizeof(T) > StructProperty::max_size ? sizeof(T) : StructProperty::max_size;

	//按照指定对齐字节数求结构体大小,用于检查指定对齐字节数是是否正确
	constexpr static std::size_t cur_elem_size = sizeof(T);
	constexpr static std::size_t next_p = ((cur_elem_size > StructProperty::cur_elem_size && cur_p % cur_align_size != 0) ? (cur_p / cur_align_size + 1) * cur_align_size : cur_p)  + cur_elem_size; 
	constexpr static std::size_t struct_size = next_p % align_size == 0 ? next_p : (next_p/align_size + 1) * align_size;
};

template
struct StructProperty
{
	constexpr static std::size_t elem_num = 1;
	constexpr static std::size_t size_sum = sizeof(T);
	constexpr static std::size_t max_size = sizeof(T);

	constexpr static std::size_t cur_elem_size = sizeof(T);
	constexpr static std::size_t next_p = sizeof(T);
	constexpr static std::size_t struct_size = next_p % align_size == 0 ? next_p : (next_p/align_size + 1) * align_size;
};

//结构体操作字段通用实现,所有操作实现均需继承该类
template using OPERATION = T(T);
template op>
struct ElementOpImp
{	
	void operator ()(T* paramter)
	{
		*paramter = op(*paramter);
	}
};

template
T default_op(T t)
{
	return t;
}

//结构体基础字段类型通用实现
//用于防止隐式转换
template
struct FieldTypeImp
{
	template operator U() = delete;
	operator T();
};

//声明字段类型模板但并不实现,只有特化的字段类型才实现
template
struct FieldType;

//结构体操作模板
template
struct StructOperation
{
	constexpr static std::size_t max_elem_size = StructProperty::max_size;
	//对齐大小不是2的整数幂就选为默认大小
	constexpr static std::size_t align_size = (t_align_size == 0 || (t_align_size & (t_align_size - 1))) ? max_elem_size : t_align_size;
	constexpr static std::size_t elem_num = StructProperty::elem_num;
	constexpr static std::size_t elem_size_sum = StructProperty::size_sum;
	constexpr static std::size_t struct_size = StructProperty::struct_size;
	template typename Op>
	void handle(T &t)
	{
		static_assert(sizeof(T) == struct_size, "exist invalid field type or struct have aligned by given size but you do not give align size or given align size is error!");
		start_p = (char *)&t;
		int num[]{element()...};
		
	}
private:
	char * start_p;
	std::size_t cur_elem_p = 0;
    std::size_t cur_elem_size = 0;
	template typename Op, typename U>
	int element()
	{
		std::size_t cur_align_size = sizeof(U) > align_size ? align_size : sizeof(U);
		if (sizeof(U) > cur_elem_size && cur_elem_p % cur_align_size != 0)
		{
			cur_elem_p = (cur_elem_p / cur_align_size + 1) * cur_align_size;
		}
		cur_elem_size = sizeof(U);
		Op()((U*)(start_p + cur_elem_p));
		cur_elem_p += cur_elem_size;
		return 0;
	}
};

//字段类型通用宏定义,定义的类型必须可用于列表初始化
//通过列表初始化与SFINAE模板规则确定结构体中每个字段的类型,并存入可变模板参数列表中
#define DEFINE_FIELD_TYPE(type) 
template<>	
struct FieldType : FieldTypeImp{};

template 
struct StructOperationstd::declval()..., std::declval>()})>,Ts...>:
StructOperation{};

//定义默认的字段操作
#define DEFINE_ELEMENT_OP(name,type,op) 
template<> 
struct name : ElementOpImp {}; 

//定义指定类型的字段操作
#define DEFINE_ELEMENT_DEFAULT_OP(name,op) 
template 
struct name : ElementOpImp {}; 

//此处声明了6个字段类型,超出这些类型编译器将会报错
DEFINE_FIELD_TYPE(int)
DEFINE_FIELD_TYPE(short)
DEFINE_FIELD_TYPE(char)
DEFINE_FIELD_TYPE(unsigned int)
DEFINE_FIELD_TYPE(unsigned short)


//n2h实现
int nl2hl(int i)
{
	return i + 4;
}

unsigned int nl2hl(unsigned int i)
{
	return nl2hl((int)i);
}

short ns2hs(short i)
{
	return i + 2;
}

unsigned short ns2hs(unsigned short i)
{
	return ns2hs((short)i);
}

DEFINE_ELEMENT_DEFAULT_OP(N2H,default_op)
DEFINE_ELEMENT_OP(N2H, int, nl2hl)
DEFINE_ELEMENT_OP(N2H, short, ns2hs)
DEFINE_ELEMENT_OP(N2H, unsigned int, nl2hl)
DEFINE_ELEMENT_OP(N2H, unsigned short, ns2hs)

template
void n2h(T &t)
{
	StructOperation().template handle(t);
}

//h2n实现
int hl2nl(int i)
{
	return i - 4;
}

unsigned int hl2nl(unsigned int i)
{
	return hl2nl((int)i);
}

short hs2ns(short i)
{
	return i - 2;
}

unsigned short hs2ns(unsigned short i)
{
	return hs2ns((short)i);
}

DEFINE_ELEMENT_DEFAULT_OP(H2N,default_op)
DEFINE_ELEMENT_OP(H2N, int, hl2nl)
DEFINE_ELEMENT_OP(H2N, short, hs2ns)
DEFINE_ELEMENT_OP(H2N, unsigned int, hl2nl)
DEFINE_ELEMENT_OP(H2N, unsigned short, hs2ns)

template
void h2n(T &t)
{
	StructOperation().template handle(t);
}

//打印结构体信息
template
T default_print_op(T t)
{
	std::cout<
	std::cout<<(int)c<<", ";
	return c;
}


DEFINE_ELEMENT_DEFAULT_OP(PRINT,default_print_op)
DEFINE_ELEMENT_OP(PRINT, char, char_print_op)

template
void print_struct(T &t)
{
	std::cout<<"["<::elem_num<<", "
				  <::max_elem_size<<", "
				  <::elem_size_sum<<", "
				  <::struct_size<<", "
				  <().template handle(t);
	std::cout<<"bb }"<int v0; short v1; unsigned int v2; char v3; unsigned short v4; char v5;};

#pragma pack(2)
struct B{int v0; short v1; unsigned int v2; char v3; unsigned short v4; char v5;};
#pragma pack()

int main()
{
	std::cout << "A:"<1,-2,3,4,5};
	n2h(a);
	print_struct(a);
	h2n(a);
	print_struct(a);

	std::cout << "B:"<-1,-2,3,4,5};
	n2h<2>(b);
	print_struct<2>(b);
	h2n<2>(b);
	print_struct<2>(b);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854019.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号