A compiling time static reflection framework for C++

static_reflect

This is a fully compiling time static reflection lightweight framework for C++.

It provides a very rich compile-time reflection function.

Below is a demo of all APIs.

environment

gcc10.3.0 & -std=c++20

For constexpr object

#include"static_reflect.h"
#include<cstdio>
using namespace std;
struct Node
{
	constexpr Node(){}
	constexpr Node(int x,float y):x{x},y{y}{} //不过构造函数还是得保持public...
private:
	int x=3;
	float y=2;
	constexpr int add(int dx,float dy)
	{
		return x+dx+y+dy;
	}
	constexpr int mul(float dx)
	{
		return x*dx*y;
	}
public:
	static consteval auto get_config() //注册反射所需的meta data
	{
		/*
		return Reflection<Node>::reflect(
			make_pair(&Node::x,"x"_ss),
			make_pair(&Node::y,"y"_ss),
			make_pair(&Node::add,"add"_ss),
			make_pair(&Node::mul,"mul"_ss)
		);
		*/
		return Reflection<Node>::regist_class(
			Reflection<Node>::regist_field(
				make_pair(&Node::x,"x"_ss),
				make_pair(&Node::y,"y"_ss)
			),
			Reflection<Node>::regist_method(
				make_pair(&Node::add,"add"_ss),
				make_pair(&Node::mul,"mul"_ss)
			)
		);
	}
};
int main()
{
	constexpr auto refl_info=static_reflect(Node);                   //得到类的反射信息
	constexpr auto methods=refl_info.get_methods();                  //得到类的所有方法的tuple
	constexpr auto method=methods.get_method("add"_ss);              //得到名称为"add"的方法
	constexpr auto fields=refl_info.get_fields();                    //得到类的所有属性的tuple
	constexpr auto field=fields.get_field("x"_ss);                   //得到名称为"x"的方法
	
	constexpr auto node=refl_info.get_instance(2,3.f);               //实例化一个对象,调用对应的构造函数
	
	constexpr auto method_name=method.get_name();                    //获取方法名称
	constexpr auto method_type=method.get_type_name();               //获取方法类型名称
	constexpr auto method_type_id=method.get_type_id();              //获取方法类型名称的哈希值
	constexpr auto method_value=method.constexpr_invoke(node,2,3.f); //调用方法
	
	constexpr auto args_types=method.get_args_type_name();           //得到该方法的参数类型名称列表
	constexpr auto return_type=method.get_return_type_name();       //得到该方法的返回值类型名称
	
	constexpr auto field_name=field.get_name();                      //得到该属性的名称
	constexpr auto field_type=field.get_type_name();                 //得到该属性的类型名称
	constexpr auto value=field.get_value(node);                      //得到该属性的值
	//field.set_value(node,2333);                                    //设置该属性的值,constexpr对象不可用.
	
	static_assert(std::is_same<decltype(refl_info.type()),Node>::value);
	static_assert(refl_info.get_name()=="Node");
	static_assert(methods.size()==2);                                         //成员函数的数量
	static_assert(fields.size()==2);                                          //成员变量的数量
	

	static_assert(std::is_same<decltype(method.return_type()),int>::value);   //得到成员函数的返回值类型(非字符串)
	static_assert(std::is_same<decltype(method.arg_type<0>()),int>::value);   //得到成员函数第0个参数类型
	static_assert(std::is_same<decltype(method.arg_type<1>()),float>::value); //得到成员函数第1个参数类型
	static_assert(args_types.size()==2);                                      //该成员函数参数个数
	static_assert(method.constexpr_invoke(node,2,3.f)==10);                   //调用构造函数构造编译期静态对象
	static_assert(method_name=="add");
	static_assert(method_type=="int (Node::*)(int, float)");
	static_assert(method_type_id==4425629840105553482ll);
	static_assert(method_value==10);
	static_assert(args_types[0]=="int");
	static_assert(args_types[1]=="float");
	static_assert(return_type=="int");
	
	static_assert(std::is_same<decltype(field.type()),int>::value);	
	static_assert(field_name=="x");
	static_assert(field_type=="int");
	static_assert(value==2);
}

For non-const object

Most functions can still be used at compile time(obviously constexpr_invoke can't be used)

int main()
{
	constexpr auto refl_info=static_reflect(Node);                   //得到类的反射信息
	constexpr auto fields=refl_info.get_fields();                    //得到类的所有属性的tuple
	constexpr auto field=fields.get_field("x"_ss);                   //得到名称为"x"的方法
	constexpr auto methods=refl_info.get_methods();                  //得到类的所有方法的tuple
	constexpr auto method=methods.get_method("add"_ss);              //得到名称为"add"的方法
	Node node=refl_info.get_instance(2,3.f);                         //实例化一个对象,调用对应的构造函数
	volatile int x=2333;
	field.set_value(node,x);                                         //修改值
	printf("%d,",field.get_value(node));                            //得到值
	printf("%d\n",method.invoke(node,2,3.f));
	
	constexpr auto args_types=method.get_args_type_name();           //得到该方法的参数类型名称列表
	constexpr auto return_type=method.get_return_type_name();       //得到该方法的返回值类型名称
	static_assert(std::is_same<decltype(method.return_type()),int>::value);   //得到成员函数的返回值类型(非字符串)
	static_assert(std::is_same<decltype(method.arg_type<0>()),int>::value);   //得到成员函数第0个参数类型
	static_assert(std::is_same<decltype(method.arg_type<1>()),float>::value); //得到成员函数第1个参数类型
	static_assert(args_types.size()==2);                                      //该成员函数参数个数
	static_assert(method.get_name()=="add");
	static_assert(method.get_type_name()=="int (Node::*)(int, float)");
	static_assert(method.get_type_id()==4425629840105553482ll);
	static_assert(args_types[0]=="int");
	static_assert(args_types[1]=="float");
	static_assert(return_type=="int");
}	

Traverse

Traverse methods and fields

#include"static_reflect.h"
#include<iostream>
using namespace std;
struct Node
{
	constexpr Node(){}
	constexpr Node(int x,float y):x{x},y{y}{} //不过构造函数还是得保持public...
private:
	int x=3;
	float y=2;
	constexpr int add(int dx,float dy)
	{
		return x+dx+y+dy;
	}
	constexpr int mul(float dx)
	{
		return x*dx*y;
	}
public:
	static consteval auto get_config() //注册反射所需的meta data
	{
		/*
		return Reflection<Node>::reflect(
			make_pair(&Node::x,"x"_ss),
			make_pair(&Node::y,"y"_ss),
			make_pair(&Node::add,"add"_ss),
			make_pair(&Node::mul,"mul"_ss)
		);
		*/
		return Reflection<Node>::regist_class(
			Reflection<Node>::regist_field(
				make_pair(&Node::x,"x"_ss),
				make_pair(&Node::y,"y"_ss)
			),
			Reflection<Node>::regist_method(
				make_pair(&Node::add,"add"_ss),
				make_pair(&Node::mul,"mul"_ss)
			)
		);
	}
};
template<std::size_t index=0>
inline constexpr void for_each_element(auto&&methods,auto&&callback)
{
	if constexpr(index<std::tuple_size<decltype(methods.metadata)>::value)
	{
		callback(index,std::get<index>(methods.metadata));
		for_each_element<index+1>(methods,callback);
	}
}
int main()
{
	constexpr auto refl_info=static_reflect(Node);
	constexpr auto methods=refl_info.get_methods();
	constexpr auto fields=refl_info.get_fields();
	constexpr auto node=refl_info.get_instance(2,3.f);
	
	methods.for_each(
		[](auto&&index,auto method){
			printf("method name:%-5s type name:%-20s\n",method.get_name().data(),method.get_type_name().data());
		}
	);
	fields.for_each(
		[=](auto&&index,auto field){
			if constexpr(std::is_same_v<decltype(field.type()),int>)
			    printf("field name:%-2s type name:%-5s value:%-2d\n",field.get_name().data(),field.get_type_name().data(),field.get_value(node));
			if constexpr(std::is_same_v<decltype(field.type()),float>)
				printf("field name:%-2s type name:%-5s value:%-2.1f\n",field.get_name().data(),field.get_type_name().data(),field.get_value(node));
		}
	);
}
Similar Resources

Meta - static reflection tools for c++. i mostly use this with entt.

meta Static reflection tools for C++. I use it with EnTT but it can work with anything. The main features the library provides are: Registering types

Jul 12, 2022

zsh module for automatically compiling sourced files

zsh module for automatically compiling sourced files

Zinit Module Motivation The module is a binary Zsh module (think about zmodload Zsh command, it's that topic) which transparently and automatically co

Dec 25, 2022

Cross compiling toolchains in Docker images

dockcross Cross compiling toolchains in Docker images. Features Pre-built and configured toolchains for cross compiling. Most images also contain an e

Jan 5, 2023

Guide to Cross Compiling on a Raspberry Pi

Guide to Cross Compilation for a Raspberry Pi Start Setup XCS and RPi Setup RPi Network and SSH Setup RPi Peripherals Setup Cross-compile environmen

Oct 4, 2022

Write snippets of C code in your txt files for notes and skip the hassle of compiling and running

Write snippets of C code in your txt files for notes and skip the hassle of compiling and running

Write snippets of C code in your txt files for notes and skip the hassle of compiling and running. Greatly helps organization and note-taking to make sure you do not miss anything.

Jun 13, 2022

ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages

ShaderConductor ShaderConductor is a tool designed for cross-compiling HLSL to other shading languages. Features Converts HLSL to readable, usable and

Dec 29, 2022

⚔️ A tool for cross compiling shaders. Convert between GLSL, HLSL, Metal Shader Language, or older versions of GLSL.

⚔️ A tool for cross compiling shaders. Convert between GLSL, HLSL, Metal Shader Language, or older versions of GLSL.

A cross compiler for shader languages. Convert between SPIR-V, GLSL / GLSL ES, HLSL, Metal Shader Language, or older versions of a given language. Cross Shader wraps glslang and SPIRV-Cross, exposing a simpler interface to transpile shaders.

Dec 30, 2022

Selective Compile-Time Reflection for C++

Introspective Some quotes from StackOverflow regarding reflection in C++: "Inspection by iterating over members of a type, enumerating its methods and

Dec 27, 2022

A modern compile-time reflection library for C++ with support for overloads, templates, attributes and proxies

refl-cpp v0.12.1 Documentation refl-cpp encodes type metadata in the type system to allow compile-time reflection via constexpr and template metaprogr

Dec 31, 2022

Compile-Time Reflection in C++ for use with Scripting Languages

Introspective Introspective is a header file that brings reflection to any class that wants it, regardless of whether the reflected member is a consta

Dec 27, 2022

json2cpp is compiles a json file into static constexpr data structures that can be used at compile time or runtime

json2cpp json2cpp is compiles a json file into static constexpr data structures that can be used at compile time or runtime. Features Literally 0 runt

Dec 22, 2022

Pharos Static Binary Analysis Framework

Automated static analysis tools for binary programs

Dec 18, 2022

ELF static analysis and injection framework that parse, manipulate and camouflage ELF files.

elfspirit elfspirit is a useful program that parse, manipulate and camouflage ELF files. It provides a variety of functions, including adding or delet

Dec 21, 2022

Qt-oriented static code analyzer based on the Clang framework

WARNING: master is the development branch. Please use the v1.10 branch. clazy v1.11 clazy is a compiler plugin which allows clang to understand Qt sem

Jan 8, 2023

Qt based simple SCADA framework, with dashboard, static and dynamic components

Qt based simple SCADA framework, with dashboard, static and dynamic components

QSimpleScada Qt/C++ based simple SCADA library for your IoT projects. We created QSimpleScada to speed up and simplify visualising any data, so we (an

Nov 28, 2022

C++ Reflection Parser / Runtime Skeleton

C++ Reflection Preface I worked on a complete reflection pipeline starting in the summer of 2015 for a game project / editor. My intent by creating th

Dec 24, 2022

Header-only, non-intrusive and macro-free runtime reflection system in C++

Header-only runtime reflection system in C++ The reflection system was born within EnTT and is developed and enriched there. This project is designed

Jan 4, 2023
A modern compile-time reflection library for C++ with support for overloads, templates, attributes and proxies

refl-cpp v0.12.1 Documentation refl-cpp encodes type metadata in the type system to allow compile-time reflection via constexpr and template metaprogr

Dec 31, 2022
C++ Reflection Parser / Runtime Skeleton

C++ Reflection Preface I worked on a complete reflection pipeline starting in the summer of 2015 for a game project / editor. My intent by creating th

Dec 24, 2022
Header-only, non-intrusive and macro-free runtime reflection system in C++

Header-only runtime reflection system in C++ The reflection system was born within EnTT and is developed and enriched there. This project is designed

Jan 4, 2023
C++ reflection library with Lua binding, and JSON and XML serialisation.

Ponder Linux & OSX: - Windows: Currents status: 3.2-alpha. API is unstable as features added/changed. New: Version 3 V1 replaced Boost with C++11. V2

Dec 28, 2022
C++ Reflection Library

!New Release - 0.9.6! RTTR C++ Reflection Library RTTR stands for Run Time Type Reflection. It describes the ability of a computer program to introspe

Jan 3, 2023
A miniature library for struct-field reflection in C++

visit_struct A header-only library providing structure visitors for C++11 and C++14. Motivation In C++ there is no built-in way to iterate over the me

Dec 12, 2022
Customizable C++17 Runtime Reflection Library

Refureku Check the Wiki for more documentation and use examples! Refureku is a powerful C++17 RTTI free runtime reflection library based on Kodgen. It

Dec 28, 2022
A miniature library for struct-field reflection in C++

visit_struct A header-only library providing structure visitors for C++11 and C++14. Motivation In C++ there is no built-in way to iterate over the me

Jan 7, 2023
C++ compile-time enum to string, iteration, in a single header file
C++ compile-time enum to string, iteration, in a single header file

Better Enums Reflective compile-time enum library with clean syntax, in a single header file, and without dependencies. In C++11, everything can be us

Dec 27, 2022
config-loader is a static reflection framework written in C++17 from parse configuration file to native data structure.

config-loader is a static reflection framework written in C++17 from parse configuration file to native data structure.

Dec 15, 2022