2026-02-11 16:14:01 -05:00
2026-02-11 16:14:01 -05:00
2026-02-11 16:14:01 -05:00
2026-02-11 16:14:01 -05:00
2026-02-11 16:14:01 -05:00
2026-02-11 16:14:01 -05:00
2026-02-11 16:14:01 -05:00

Core_IO

IO foundational classes

IO classes which optimize super well, super fast, super memory efficient.
JSON is based on sajson which is nearly as fast as memcpy (which blows my mind).

Building

IO is header only.

How to use

Declare your data


namespace my_namespace {

struct MyOtherData {
	float f;
} ;

struct MyData {
	char c;
	int i;
	std::string s;
	MyOtherData o;
} ;

} // my_namespace

Somewhere in the same namespace, declare the serializer:


namespace my_namespace {

template<typename IO>
void io_(IO &io, MyOtherData &v)
{
	io.object(
		"f", v.f
	);
)


template<typename IO>
void io_(IO &io, MyData &v)
{
	io.object(
		"c", v.c,
		"i", v.i,
		"s", v.s,
		"o", v.o
	);
)

} // my_namespace

To serialize and deserialize as json:


#include <tjp/core/json/in_sajson.h>
#include <tjp/core/json/out.h>

namespace any_namespace {

void somewhere ()
{
	my_namespace::MyData myData;
	auto serialized = tjp::core::io::json::serialize(myData);
	auto deserialized = tjp::core::io::json::deserialize<my_namespace::MyData>(serialized);
}

} // any_namespace

To serialize and deserialize as binary:

#include <tjp/core/bin/in.h>
#include <tjp/core/bin/out.h>

namespace any_namespace {

void somewhere ()
{
	my_namespace::MyData myData;
	auto serialized = tjp::core::io::bin::serialize(myData);
	auto deserialized = tjp::core::io::bin::deserialize<my_namespace::MyData>(serialized);
}

} // any_namespace

To do versioning

I use versioning, however I declared it outside the scope of the library.

The method I ended up using was to deserialize a version number at the beginning of a deserialization and store in the IO class. Then when deserializing data which is versioned, check the version number and dispatch to the appropriate function.

It ends up looking like this:

template<typename IO>
void io_(IO &io, TimeSpecification &v, serializer::Version<100> &&)
{
	io.object(
		"clock", v.clock,
		"bounds", v.bounds
	);
}

template<typename IO>
void io_(IO &io, TimeSpecification &v, serializer::Version<104> &&)
{
	io.object(
		"clock", v.clock,
		"bounds", v.bounds,
		"flags", v.flags
	);
}


template<typename IO>
void io_(IO &io, TimeSpecification &v)
{
	if (io.version.my_version_number < 104)
		return io_(io, v, serializer::Version<104>{});

	return io_(io, v, serializer::Version<104>{});
}

You can make your own serialization IO by implementing a new IO class

It's not trivial, but it's not hard.

Generally, I'll be putting in some time to clean up these IO classes in the end of 2025.

Other examples

Look at Core_IO/bin/_tests/IO_bin.cpp for more examples on how to use this library.

Description
No description provided
Readme 132 KiB
Languages
C++ 99.9%
C 0.1%