universal serialization engine

A Universal Serialization Engine Based on compile-time Reflection

iguana is a modern, universal and easy-to-use serialization engine developed in c++17.

Motivation

Serialize an object to any other format data with compile-time reflection, such as json, xml, binary, table and so on. This library is designed to unify and simplify serialization in a portable cross-platform manner. This library is also easy to extend, and you can serialize any format of data with the library. This library provides a portable cross-platform way of:

  • serialization of json
  • serialization of xml
  • serialization of any customized format

Tutorial

This Tutorial is provided to give you a view of how iguana works for serialization.

Serialization of json

The first thing to do when you serialize an object is to define meta data. There is an example of defining meta data.

struct person
{
	std::string  name;
	int          age;
};

REFLECTION(person, name, age) //define meta data

Defining meta data is very simple, and just needs to define in a REFLECTION macro.

Now let's serialize person to json string.

person p = { "tom", 28 };

iguana::string_stream ss;
iguana::json::to_json(ss, p);

std::cout << ss.str() << std::endl; 

This example will output:

{"name":"tom","age":28}

Serializing person to json string is also very simple, just need to call to_json method, there is nothing more.

How about deserialization of json? Look at the follow example.

const char * json = "{ \"name\" : \"tom\", \"age\" : 28}";

person p;
iguana::json::from_json(p, json);

It's as simple as serialization, just need to call from_json method.

Serialization of xml

Serialization of xml is similar to json. The first step is also defining meta data as above. This is a complete example.

person p = {"admin", 20};

iguana::string_stream ss;
iguana::xml::to_xml(ss, p);

std::cout << ss.str() << std::endl;

std::string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\">  <name>buke</name> <id>1</id>";
iguana::xml::from_xml(p, xml.data(), xml.length());

A complicated example

iguana can deal with objects which contain another objects and containers. Here is the example:

At first, we define the meta data:

struct one_t
{
	int id;
};
REFLECTION(one_t, id);

struct two
{
	std::string name;
	one_t one;
	int age;
};
REFLECTION(two, name, one, age);

struct composit_t
{
	int a;
	std::vector<std::string> b;
	int c;
	std::map<int, int> d;
	std::unordered_map<int, int> e;
	double f;
	std::list<one_t> g;
};
REFLECTION(composit_t, a, b, c, d, e, f, g);

Then call the simple interface:

one_t one = { 2 };
composit_t composit = { 1,{ "tom", "jack" }, 3,{ { 2,3 } },{ { 5,6 } }, 5.3,{ one } };
iguana::string_stream ss;
iguana::json::to_json(ss, composit);
std::cout << ss.str() << std::endl;

const char* str_comp = R"({"a":1, "b":["tom", "jack"], "c":3, "d":{"2":3,"5":6},"e":{"3":4},"f":5.3,"g":[{"id":1},{"id":2}])";
composit_t comp;
iguana::json::from_json(comp, str_comp);

How to solve the problem of unicode path in a json file?

If there is an unicode string as a path in a json file, however iguana parse the file as utf-8, so maybe you can see some strange characters after parse.

It's ok, because you see the utf-8 strings. The problem is you can't use the string directly, such as use std::ifstream to open the file with the unicode string path.

We can slove the problem1 easily with c++17:

	//the p.path is a unicode string path
	std::ifstream in(std::filesystem::u8path(p.path)); //std::filesystem::u8path help us
	//now you can operate the file

Full sources:

F.A.Q

  • Question: Why is the library called iguana?

    • Answer: I think serialization is like an iguana, because the only difference is the displaying format, however the meta data is never changed. With changeless meta data and reflection, you can serialize an object to any format, which is like how an iguana does.
  • Question: Does iguana support raw pointer?

    • Answer: No. iguana doesn't support raw pointer, but it will support smart pointer in the future.
  • Question: Is iguana thread-safe?

    • Answer: Not yet, but it's not a problem, you can use lock before calling from_json or to_json.
  • Question: Is iguana high performance?

    • Answer: Yes, it is, because iguana is based on compile-time reflection.
  • Question: I found a bug, how could I report?

    • Answer: Create an issue on GitHub with a detailed description.

Update

  1. Support C++17
  2. Support disorderly parse json, a new interface from_json0 do this, however it is slower than from_json.
Owner
qicosmos
purecpp.org 微信公账号purecpp
qicosmos
Comments
  • 解析集合数据的时候,from_json会产生重复的记录

    解析集合数据的时候,from_json会产生重复的记录

    #include <assert.h> void test_v() { client::person p1 = { "tom", 20 }; client::person p2 = { "jack", 19 }; client::person p3 = { "mike", 21 };

    std::vector<client::person> v{ p1, p2, p3 };
    iguana::string_stream ss;
    iguana::json::to_json(ss, v);
    auto json_str = ss.str();
    std::cout << json_str << std::endl;
    
    std::vector<client::person> v1;
    iguana::json::from_json(v1, json_str.data(), json_str.length());
    
    assert(v == v1);
    
    // 测试嵌套的数据
    client::person allPerson;
    allPerson.age = 20 + 19 + 21;
    allPerson.name = json_str; // vector<>转换过来的json字符串
    
    ss.clear();
    iguana::json::to_json(ss, allPerson);
    json_str = ss.str();
    std::cout << json_str << std::endl;
    
    client::person allPerson2;
    iguana::json::from_json(allPerson2, json_str.data(), json_str.length());
    assert(allPerson2 == allPerson);
    
    
    // bug: 有重复的记录
    iguana::json::from_json(v1, allPerson2.name.data(), allPerson2.name.length());
    assert(v == v1);
    

    }

  • to_json 不支持int64_t uint64_t  等

    to_json 不支持int64_t uint64_t 等

    #include "json.hpp"
    #include "reflection.hpp"
    struct ita
    {
    	int64_t b;
    };
    REFLECTION(ita,  b)
    int main()
    {
         ita f{1 };
         iguana::string_stream ss;
         iguana::json::to_json(ss, f);
         auto json_str = ss.str();
         std::cout << json_str << std::endl;
         return 0;
    }
    

    编译报错(vs2017)

  • 不能正常解析字段

    不能正常解析字段

    namespace Model {
        struct BookData {
            std::string name;
            std::string pubs;
            int pages;
            std::string types;
        };
        REFLECTION(BookData, name, pages, pubs, types);
    }
    
    const char * bookJson = "{\"name\":\"my book\",\"types\":\"aaa\",\"pages\":11,\"pubs\":\"bbb\"}";
    Model::BookData book;
    iguana::json::from_json(book, bookJson);
    cout << book.name << endl;//正常输出
    cout << book.types << endl;//没有输出
    
  • 反序列化时的问题?

    反序列化时的问题?

        template<typename T>
        void check_result(T val, char const *str){
            if(val == 0 && strcmp(str,"0") != 0){
                g_has_error = true;
            }
        }
    

    在源代码里面看到有这行代码,序列化std::map<int,自定义结构>时,如果key是0,在某些时候from_json(对象,JSON字符串)会返回false,,但是检查对象时,发现数据都已经反序列化成功。

  • 反序列化会陷入死循环的问题?

    反序列化会陷入死循环的问题?

    struct A { int a; std::string b; }; struct B { A a; std::string c; }; REFLECTION(A, a,b); REFLECTION(B, a,c);

    序列化:{"a":{"a":1,"b":"123"},"c":"123"} json没问题。 但是序列化:{"a":{"a":1},"c":"123"} 会陷入死循环

  • 怎么利用reflection17.hpp实现同名字段拷贝?

    怎么利用reflection17.hpp实现同名字段拷贝?

    struct AAA{ int a; string b; int c; };

    struct BBB{ string b; int c; int d; };

    AAA a; BBB b;

    a.b="aaa"; a.c=123;

    b.b ="bbb"; b.d=754;

    func(b, a);

    func()执行完后 b.b为"aaa" ,b.c为123 ,b.d不变仍为754

  • json字符串解析时有个问题不清楚,想请问下作者

    json字符串解析时有个问题不清楚,想请问下作者

    struct string_ref {
                    char const *str;
                    size_t len;
    
                    int length() const {
                        auto size = len;
                        for (size_t i = 0; i < len; ++i) {
                            if (str[i] == 92 || str[i] == 116 || str[i] == 50) // 92: ‘\’, 116: ‘t’, 50: ‘2’
                                size -= 1;
                        }
    
                        return static_cast(size);
                    }
    
                    bool operator!=(const char *data) const {
                        auto const str_length = strlen(data);
                        if (len != str_length) {
                            if (length() != str_length)
                                return true;
                        }
    
                        for (size_t i = 0; i < str_length; ++i) {
                            if (str[i] != data[i]) {
                                return true;
                            }
                        }
                        return false;
                    }
                };
            } 

    不知道上面的length() 函数中为何当str[i]=92,116,50的时候size要-1?

  • build error in CentOS7 env

    build error in CentOS7 env

    I met build error in my env. Do we have tutorial about how to build this project in Linux env? my gcc version is 5.30 Build log: [[email protected] build]$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/local/gcc/libexec/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ./configure --prefix=/usr/local/gcc --enable-threads=posix --disable-checking --enable-languages=c,c++ --disable-multilib --with-gmp=/usr/local/lib --with-mpfr=/usr/local/lib --with-mpc=/usr/local/lib Thread model: posix gcc version 5.3.0 (GCC) [[email protected] build]$ vi /home/mcong/study/github/iguana/reflection.hpp [[email protected] build]$ make Scanning dependencies of target json_example [ 33%] Building CXX object CMakeFiles/json_example.dir/example/json_example.cpp.o In file included from /home/mcong/study/github/iguana/json.hpp:8:0, from /home/mcong/study/github/example/json_example.cpp:1: /home/mcong/study/github/iguana/reflection.hpp:326:55: error: global qualification of class name is invalid before ‘{’ token template<>struct ::iguana_reflect_members<STRUCT_NAME>{
    ^ /home/mcong/study/github/iguana/reflection.hpp:338:5: note: in expansion of macro ‘MAKE_META_DATA_IMPL’ MAKE_META_DATA_IMPL(STRUCT_NAME, MAKE_ARG_LIST(N, &STRUCT_NAME::OBJECT, VA_ARGS)) ^ /home/mcong/study/github/iguana/reflection.hpp:343:1: note: in expansion of macro ‘MAKE_META_DATA’ MAKE_META_DATA(STRUCT_NAME, GET_ARG_COUNT(VA_ARGS), VA_ARGS) ^ /home/mcong/study/github/example/json_example.cpp:11:2: note: in expansion of macro ‘REFLECTION’ REFLECTION(person, name, age); ^ /home/mcong/study/github/example/json_example.cpp: In function ‘int main()’: /home/mcong/study/github/example/json_example.cpp:19:29: error: no matching function for call to ‘to_json(iguana::string_stream&, client::person&)’ iguana::json::to_json(ss, p); ^ In file included from /home/mcong/study/github/example/json_example.cpp:1:0: /home/mcong/study/github/iguana/json.hpp:138:7: note: candidate: template<class Stream, class T> std::enable_if_t<iguana::is_reflection::value> iguana::json::to_json(Stream&, T&&) auto to_json(Stream& s, T &&t) -> std::enable_if_t<is_reflection::value> ^ /home/mcong/study/github/iguana/json.hpp:138:7: note: template argument deduction/substitution failed: /home/mcong/study/github/iguana/json.hpp:161:7: note: candidate: template<class Stream, class T> void iguana::json::to_json(Stream&, const std::vector&) void to_json(Stream& s, const std::vector &v) { ^ /home/mcong/study/github/iguana/json.hpp:161:7: note: template argument deduction/substitution failed: /home/mcong/study/github/example/json_example.cpp:19:29: note: ‘client::person’ is not derived from ‘const std::vector’ iguana::json::to_json(ss, p); ^ In file included from /home/mcong/study/github/example/json_example.cpp:1:0: /home/mcong/study/github/iguana/json.hpp:166:7: note: candidate: template<class Stream, class ... Args> void iguana::json::to_json(Stream&, std::tuple<_Elements ...>) void to_json(Stream& s, std::tuple<Args...> tp) { ^ /home/mcong/study/github/iguana/json.hpp:166:7: note: template argument deduction/substitution failed: /home/mcong/study/github/example/json_example.cpp:19:29: note: ‘client::person’ is not derived from ‘std::tuple<_Elements ...>’ iguana::json::to_json(ss, p); ^ /home/mcong/study/github/example/json_example.cpp:25:64: error: no matching function for call to ‘from_json(client::person&, const char*, std::__cxx11::basic_string::size_type)’ iguana::json::from_json(p2, json_str.data(), json_str.length()); ^ In file included from /home/mcong/study/github/example/json_example.cpp:1:0: /home/mcong/study/github/iguana/json.hpp:1030:7: note: candidate: template<class T, class> void iguana::json::from_json(T&&, const char*, size_t) void from_json(T &&t, const char *buf, size_t len = -1) { ^ /home/mcong/study/github/iguana/json.hpp:1030:7: note: template argument deduction/substitution failed: make[2]: *** [CMakeFiles/json_example.dir/example/json_example.cpp.o] Error 1 make[1]: *** [CMakeFiles/json_example.dir/all] Error 2 make: *** [all] Error 2

  • 我为example.cpp增加了示例和注释

    我为example.cpp增加了示例和注释

    #include <iostream>
    #include "json.hpp"
    #include "xml.hpp"
    
    struct person
    {
    	std::string  name;
    	int          age;
    };
    REFLECTION(person, name, age)
    /* REFLECTION(person, name, age)展开后的代码如下
    constexpr std::array<const char*, 2> arr_person = { "name" , "age" };
    template<>
    struct Members<person> {
    	constexpr decltype(auto) static apply() { 
    		return std::make_tuple(&person::name, &person::age); 
    	} 
    	using type = void; 
    	constexpr static const char *name = "person"; 
    	constexpr static const size_t value = 2; 
    	constexpr static const std::array<const char*, value>& arr = arr_person;
    };
    */
    
    struct one_t
    {
    	int id;
    };
    REFLECTION(one_t, id);
    
    struct third_t
    {
    	std::string name;
    	one_t one;
    	int age;
    };
    REFLECTION(third, name, one, age);
    
    struct composit_t
    {
    	int a;
    	std::vector<std::string> b;
    	int c;
    	std::map<int, int> d;
    	std::unordered_map<int, int> e;
    	double f;
    	std::list<one_t> g;
    };
    REFLECTION(composit_t, a, b, c, d, e, f, g);
    
    void test_json()
    {
    	person p;
    	const char * json = "{ \"name\" : \"tom\", \"age\" : 28}";
    	iguana::json::from_json(p, json);
    
    	iguana::string_stream ss;
    	iguana::json::to_json(ss, p);
    	std::cout << ss.str() << std::endl;
    
    	one_t one = { 2 };
    	composit_t composit = { 1,{ "tom", "jack" }, 3,{ { 2,3 } },{ { 5,6 } }, 5.3,{ one } };
    	iguana::string_stream sst;
    	iguana::json::to_json(sst, composit);
    	std::cout << sst.str() << std::endl;
    
    	const char* str_comp = R"({"a":1, "b":["tom", "jack"], "c":3, "d":{"2":3,"5":6},"e":{"3":4},"f":5.3,"g":[{"id":1},{"id":2}])";
    	composit_t comp;
    	iguana::json::from_json(comp, str_comp);
    }
    
    //void performance()
    //{
    //	person obj;
    //	char * json = "{ \"Name\" : \"Boo\", \"Age\" : 28}";
    //	ajson::load_from_buff(obj, json);
    //
    //	const size_t LEN = 1000000;
    //
    //	//反序列化
    //	std::cout << "ajson deserialize: ";
    //	boost::timer t;
    //	for (size_t i = 0; i < LEN; i++)
    //	{
    //		ajson::load_from_buff(obj, json);
    //	}
    //	std::cout << t.elapsed() << std::endl;
    //
    //	std::cout << "reflib deserialize: ";
    //	t.restart();
    //	for (size_t i = 0; i < LEN; i++)
    //	{
    //		iguana::json::from_json(obj, json);
    //	}
    //	std::cout << t.elapsed() << std::endl;
    //
    //	//序列化
    //	std::cout << "ajson serialize: ";
    //	t.restart();
    //	ajson::string_stream ss1;
    //
    //	for (size_t i = 0; i < LEN; i++)
    //	{
    //		ss1.clear();
    //		ajson::save_to(ss1, obj);
    //	}
    //	std::cout << t.elapsed() << std::endl;
    //
    //	std::cout << "reflib serialize: ";
    //	t.restart();
    //
    //	iguana::json::string_stream ss;
    //	for (size_t i = 0; i < LEN; i++)
    //	{
    //		ss.clear();
    //		iguana::json::to_json(ss, obj);
    //	}
    //	std::cout << t.elapsed() << std::endl;
    //}
    
    void test_xml()
    {
    	person p = {"admin", 20};
    	iguana::string_stream ss;
    	iguana::xml::to_xml(ss, p);
    	std::cout << ss.str() << std::endl;
    
    	ss.clear();
    	two t = { "test", {2}, 4 };
    	iguana::xml::to_xml(ss, t);
    	auto result = ss.str();
    	std::cout << result << std::endl;
    
    	std::string xml = "			<?xml version=\"1.0\" encoding=\"UTF-8\">  <name>buke</name> <one><id>1</id></one>  <age>2</age>";
    	two t1;
    	iguana::xml::from_xml(t1, xml.data(), xml.length());
    }
    
    template<typename T, typename = std::enable_if_t<is_reflection<T>::value>>
    void test_nest_read(T &&t, int indent = 0) {
    	using namespace std;
    	for_each(std::forward<T>(t),	[=](auto &v, size_t I, bool is_last) {
    		for (size_t i = 0; i < indent; i++) 	cout << "  ";
    		cout << I << " : " << get_name<T>(I) << " = " << v << endl;
    	},
    		[=](auto &o, size_t I, bool is_last) {
    		for (size_t i = 0; i < indent; i++)		cout << "  ";
    		cout << I << " : 下面是嵌入的成员" << typeid(o).name() << endl;
    		test_nest_read(o, indent + 1);
    	});
    }
    
    void test_reflection()
    {
    	person p = { "admin", 20 };
    	
    	constexpr auto fieldname = get_name<person, 0>();	//"name", const char* const. get_name直接返回Members<person>::arr[0]
    	auto val = get<0>(p);								//"admin",std::basic_string. person.*(&person::name)
    
    	//person只含有非反射类型成员
    	for_each(p, [](const auto& item, size_t index, bool is_last) {
    		std::cout << index <<" "<< item << std::endl;
    	});
    	
    	std::cout << std::endl;
    	
    	two_t two = { "test",{ 2 }, 4 };
    	//two只嵌套了(一层)一个映射类型成员
    	for_each(two, [](const auto& item, size_t index, bool is_last) { //处理非反射类型成员
    		std::cout << index << " " << item << std::endl;
    	}, [](const auto& o, size_t index, bool is_last) {				//处理反射类型成员
    		std::cout << index << " "<<typeid(o).name()<< std::endl;
    	});
    
    	std::cout << std::endl;
    	//test_nest_read可以处理无限映射类型嵌套,但是不能处理容器如vector、map,详细可以参考test_json()
    	third_t third = { "test",{ 2 }, 4 };
    	test_nest_read(third);
    }
    
    int main()
    {
    	test_reflection();
    //	test_json();
    //	test_xml();
    }
    
    
  • 序列化时容器为空时有小问题

    序列化时容器为空时有小问题

    容器为空时,序列化时 未做判断

    	template<typename InputIt, typename T, typename F>
    	T join(InputIt first, InputIt last, const T &delim, const F &f) {
    		if (first == last) return T();
    		T t = f(*first++);
    		while (first != last) {
    			t += delim;
    			t += f(*first++);
    		}
    		return t;
    	}
    
    	template<typename Stream, typename InputIt, typename T, typename F>
    	void join(Stream& ss, InputIt first, InputIt last, const T &delim, const F &f) {
    		if (first == last) return;
    		f(*first++);
    		while (first != last) {
    			ss.put(delim);
    			f(*first++);
    		}
    	}
    
  • remove constexpr in some non-constexpr environment

    remove constexpr in some non-constexpr environment

    In MacOS with Clang, the code will fail to compile because std::string doesn't provide a constexpr constuctor so that it can not be in constexpr environment. Remove some usage of constexpr to extinguish such bugs.

  • 结构体中的第一个序位的float的值,被修改为大的正值。

    结构体中的第一个序位的float的值,被修改为大的正值。

    struct ca{

    std::string c_id; std::string ca_id; std::string c_name; float pan; // =0.0; float tilt; float zoom; } REFLECTION(ca, c_id,ca_id, c_name, pan, tilt , zoom)

    执行完上面的定义后,在一个执行函数中定义这个ca类 ca tb_ca; 发现成员变量的值 tb_ca.pan 不为接近于0的一个数,而为一个正的有意义的值。

    请问是内存溢出的错误嘛,该如何修改。

  • 结构体包含由子结构体转换成的json字符串,无法反解回结构体

    结构体包含由子结构体转换成的json字符串,无法反解回结构体

    以“六年级-三班-某学生”为例,学生由结构体转换为json字符,作为班级的成员; 班级由结构体转换为json字符,作为年级的成员; 由年级json字符无法解析出classParm成员变量,解析出的结构只有"{"

    #include "mainwindow.h"
    #include <QApplication>
    #include <iostream>
    #include "../iguana/iguana/json.hpp"
    // 六年级-三班-某学生
    struct Person
    {
        std::string  name;
        int          age;
    };
    REFLECTION(Person, name, age);
    
    struct Class   
    {
        int classID;
        std::string personParm;
    };
    REFLECTION(Class, classID, personParm)
    
    struct Grade   
    {
        int gradeID;
        std::string classParm;  
    };
    REFLECTION(Grade, gradeID, classParm)
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    //    MainWindow w;
    //    w.show();
        Person p;
        p.age = 10;
        p.name = "suli";
        iguana::string_stream pp;
        iguana::json::to_json(pp, p);
        std::cout << pp.str() << std::endl;
        Person res_p;
        iguana::json::from_json(res_p, pp.str().c_str());
    
        Class c;
        c.classID = 3;
        c.personParm = pp.str();
        iguana::string_stream cc;
        iguana::json::to_json(cc, c);
        std::cout << cc.str() << std::endl;
        //const char* dd= "{\"classID\":3,\"personParm\":\"{\\\"name\\\":\\\"suli\\\",\\\"age\\\":10}\"}";
        Class res_c;
        iguana::json::from_json(res_c, cc.str().c_str());
    
        Grade g;
        g.gradeID = 6;
        g.classParm = cc.str();
        iguana::string_stream gg;
        iguana::json::to_json(gg, g);
        std::cout << gg.str().c_str() << std::endl;
        Grade res_g;
        iguana::json::from_json(res_g, gg.str().c_str());
    
        Grade res;
        iguana::json::from_json(res, gg.str().c_str());
        return a.exec();
    }
    
  • 解析时没有安全检查

    解析时没有安全检查

    我在尝试使用这个库时遇到一些问题,对于json字符串的解析,没有安全检查,比如某个字段类型不正确,不存在,iguana::json::from_json0()会仍然返回true,并且在对象中使用不正确的值. 举个例子: struct test { std::string username; std::string password; long long id; bool error; }; REFLECTION(test, username, password, id, error);

    int main(void) { test test1; std::string str1 = "{"username1":"test","password":"test","id": 10.1, "error": false}"; auto ret = iguana::json::from_json0(test1, str1.c_str(), str1.length()); std::cout << test1.username << std::endl; std::cout << test1.password << std::endl; std::cout << test1.id << std::endl; std::cout << std::boolalpha << test1.error << std::endl; std::cout << std::boolalpha << ret << std::endl; return 0; } 以上代码,json字符串不存在username这个key,并且id的类型也不正确,但是解析仍然返回true. 我认为该库无法用于生产环境,因为解析的正确性不应该由使用库的用户来检查.

  • 是否可以加一个set_field_value的方法,便于通过某个字符串名称来设置对象相应成员的值

    是否可以加一个set_field_value的方法,便于通过某个字符串名称来设置对象相应成员的值

    `template<typename T, typename V> void set_field_value(T& to_obj, std::string_view to_field_name, const V& from_v) { using M = decltype(iguana_reflect_members(to_obj)); auto tp = M::apply_impl(); constexpr auto Size = M::value(); auto index = iguana::get_index(to_field_name); tuple_switch(index, tp, [&](auto& v) { using type_v = decltype(std::declval().*std::declval<decltype(v)>()); to_obj.*v = (type_v)from_v; }, std::make_index_sequence{}); } /////////////////////////////////////////////// struct person { std::string name; int age = 0; };

    REFLECTION(person, age, name);

    int main() { person p; iguana::set_field_value(p, "name", "Tom"); iguana::set_field_value(p, "age", 20); return getchar(); }`

Serialization framework for Unreal Engine Property System that just works!

DataConfig Serialization framework for Unreal Engine Property System that just works! Unreal Engine features a powerful Property System which implemen

Jun 12, 2022
Your binary serialization library

Bitsery Header only C++ binary serialization library. It is designed around the networking requirements for real-time data delivery, especially for ga

Jun 15, 2022
Jun 16, 2022
Cap'n Proto serialization/RPC system - core tools and C++ library
Cap'n Proto serialization/RPC system - core tools and C++ library

Cap'n Proto is an insanely fast data interchange format and capability-based RPC system. Think JSON, except binary. Or think Protocol Buffers, except

Jun 23, 2022
A C++11 library for serialization
A C++11 library for serialization

cereal - A C++11 library for serialization cereal is a header-only C++11 serialization library. cereal takes arbitrary data types and reversibly turns

Jun 23, 2022
FlatBuffers: Memory Efficient Serialization Library

FlatBuffers FlatBuffers is a cross platform serialization library architected for maximum memory efficiency. It allows you to directly access serializ

Jun 20, 2022
Yet Another Serialization
Yet Another Serialization

YAS Yet Another Serialization - YAS is created as a replacement of boost.serialization because of its insufficient speed of serialization (benchmark 1

Jun 20, 2022
Binary Serialization

Binn Binn is a binary data serialization format designed to be compact, fast and easy to use. Performance The elements are stored with their sizes to

Jun 13, 2022
An implementation of the MessagePack serialization format in C / msgpack.org[C]

CMP CMP is a C implementation of the MessagePack serialization format. It currently implements version 5 of the MessagePack Spec. CMP's goal is to be

May 27, 2022
MPack - A C encoder/decoder for the MessagePack serialization format / msgpack.org[C]

Introduction MPack is a C implementation of an encoder and decoder for the MessagePack serialization format. It is: Simple and easy to use Secure agai

May 24, 2022
Simple C++ 20 Serialization Library that works out of the box with aggregate types!

BinaryLove3 Simple C++ 20 Serialization Library that works out of the box with aggregate types! Requirements BinaryLove3 is a c++20 only library.

Dec 23, 2021
Zmeya is a header-only C++11 binary serialization library designed for games and performance-critical applications

Zmeya Zmeya is a header-only C++11 binary serialization library designed for games and performance-critical applications. Zmeya is not even a serializ

Jun 6, 2022
CppSerdes is a serialization/deserialization library designed with embedded systems in mind
CppSerdes is a serialization/deserialization library designed with embedded systems in mind

A C++ serialization/deserialization library designed with embedded systems in mind

Jun 3, 2022
Header-only library for automatic (de)serialization of C++ types to/from JSON.

fuser 1-file header-only library for automatic (de)serialization of C++ types to/from JSON. how it works The library has a predefined set of (de)seria

Jun 4, 2022
Yet Another Serialization
Yet Another Serialization

YAS Yet Another Serialization - YAS is created as a replacement of boost.serialization because of its insufficient speed of serialization (benchmark 1

Sep 7, 2021
C++17 library for all your binary de-/serialization needs

blobify blobify is a header-only C++17 library to handle binary de-/serialization in your project. Given a user-defined C++ struct, blobify can encode

May 29, 2022
Yet another JSON/YAML/BSON serialization library for C++.
Yet another JSON/YAML/BSON serialization library for C++.

ThorsSerializer Support for Json Yaml Bson NEW Benchmark Results Conformance mac linux Performance max linux For details see: JsonBenchmark Yet anothe

Jun 15, 2022
Cista is a simple, high-performance, zero-copy C++ serialization & reflection library.

Simple C++ Serialization & Reflection. Cista++ is a simple, open source (MIT license) C++17 compatible way of (de-)serializing C++ data structures. Si

Jun 11, 2022
A lightweight C++20 serialization framework

zpp::bits A modern C++20 binary serialization library, with just one header file. This library is a successor to zpp::serializer. The library tries to

Jun 9, 2022