All Projects → eliasdaler → Metastuff

eliasdaler / Metastuff

Licence: mit
Code I use in my game for all serialization/deserialization/introspection stuff

Programming Languages

cpp
1120 projects
metaprogramming
66 projects

Projects that are alternatives of or similar to Metastuff

Fasteasymapping
A tool for fast serializing & deserializing of JSON
Stars: ✭ 556 (+64.99%)
Mutual labels:  serialization, json-serialization
Savegamefree
Save Game Free is a free and simple but powerful solution for saving and loading game data in unity.
Stars: ✭ 279 (-17.21%)
Mutual labels:  serialization, json-serialization
Fastjson
A fast JSON parser/generator for Java.
Stars: ✭ 23,997 (+7020.77%)
Mutual labels:  serialization, json-serialization
Eminim
JSON serialization framework for Nim, works from a Stream directly to any type and back. Depends only on stdlib.
Stars: ✭ 32 (-90.5%)
Mutual labels:  serialization, json-serialization
Mongoengine Goodjson
More human-readable json serializer/deserializer for MongoEngine
Stars: ✭ 56 (-83.38%)
Mutual labels:  serialization, json-serialization
JsonFormatter
Easy, Fast and Lightweight Json Formatter. (Serializer and Deserializer)
Stars: ✭ 26 (-92.28%)
Mutual labels:  serialization, json-serialization
Thorsserializer
C++ Serialization library for JSON
Stars: ✭ 241 (-28.49%)
Mutual labels:  serialization, json-serialization
Panko serializer
High Performance JSON Serialization for ActiveRecord & Ruby Objects
Stars: ✭ 266 (-21.07%)
Mutual labels:  serialization, json-serialization
Inquiry Deprecated
[DEPRECATED]: Prefer Room by Google, or SQLDelight by Square.
Stars: ✭ 264 (-21.66%)
Mutual labels:  serialization
Cattrs
Complex custom class converters for attrs.
Stars: ✭ 286 (-15.13%)
Mutual labels:  serialization
Watson
WATSON: Wasted but Amazing Turing-incomplete Stack-based Object Notation
Stars: ✭ 258 (-23.44%)
Mutual labels:  serialization
Permazen
Language-Natural Persistence Layer for Java
Stars: ✭ 265 (-21.36%)
Mutual labels:  serialization
Surging
Surging is a micro-service engine that provides a lightweight, high-performance, modular RPC request pipeline. The service engine supports http, TCP, WS,Grpc, Thrift,Mqtt, UDP, and DNS protocols. It uses ZooKeeper and Consul as a registry, and integrates it. Hash, random, polling, Fair Polling as a load balancing algorithm, built-in service gove…
Stars: ✭ 3,088 (+816.32%)
Mutual labels:  json-serialization
Protobuf
C# code generator for reading and writing the protocol buffers format
Stars: ✭ 260 (-22.85%)
Mutual labels:  serialization
Bebop
An extremely simple, fast, efficient, cross-platform serialization format
Stars: ✭ 305 (-9.5%)
Mutual labels:  serialization
Play Json
The Play JSON library
Stars: ✭ 254 (-24.63%)
Mutual labels:  serialization
Fspickler
A fast multi-format message serializer for .NET
Stars: ✭ 299 (-11.28%)
Mutual labels:  serialization
Flatbuffers
FlatBuffers: Memory Efficient Serialization Library
Stars: ✭ 17,180 (+4997.92%)
Mutual labels:  serialization
Marshmallow dataclass
Automatic generation of marshmallow schemas from dataclasses.
Stars: ✭ 255 (-24.33%)
Mutual labels:  serialization
Kotlinx.serialization
Kotlin multiplatform / multi-format serialization
Stars: ✭ 3,550 (+953.41%)
Mutual labels:  serialization

Meta stuff WIP

This is the code I use in my game for all serialization/deserialization/introspection stuff.

This article explains how it can be used and how it was made in detail.

See metastuff-clang-generator for automatic registration of classes in MetaStuff!

Features

  • Strongly typed and doesn't use RTTI or virtual functions in any way. You can iterate over class members and you still know member's type, there's no type erasure and it's all very fast
  • No dependencies. You have to use modern C++ compiler which supports C++14, though. (VS 2015, GCC 5+, Clang 3.8)
  • Serialization is not limited to any format. There's no standard way of doing serialization. You can implement it yourself for your own format. (See JSON example to see how it can be done)
  • You don't need to modify classes that you want to serialize/deserialize. Everything is done through providing template specializations of MetaStuff's registerMembers<T> function for your classes. No modifications to classes you want to serialize are needed!

The lib is still in development, so it's not recommended to use it for anything really serious as lots of stuff can change! Still, use it as you like, it's MIT licensed after all.

All suggestions about improving the lib are welcome. I know it isn't perfect, so let's make it better together. :)

Requirements

  • Compiler with C++14 support (I managed to compile it with Visual Studio 2015, GCC 5.0, Clang 3.8)

Dependencies

  • Just standard library. (JSON for Modern C++ is used in example, but you can use any library you want for serialization)

Example

See example for complete example of JSON serialization.

Suppose you have classes like this:

struct Person {
    void setAge(int a)
    {
        if (a >= 0 && a < 128) { // sorry, if you're older than 128
            age = a;
        } else {
            std::cout << "Can't set age. " << a << " is out of allowed range\n";
        }
    }

    int getAge() const { return age; }
    
    void setName(const std::string& name) { this->name = name; }

    const std::string& getName() const { return name; }

    int age;
    std::string name;
    float salary;
    std::unordered_map<std::string, std::vector<MovieInfo>> favouriteMovies;
};

struct MovieInfo {
    std::string name;
    float rating;
};

And you want to serialize them to some format (for example, JSON). Or perhaps you want to add some GUI which will let you edit each member easily. No problem, just write these static functions,

#include "Meta.h"

namespace meta
{

template <>
inline auto registerMembers<Person>()
{
    return members(
        member("age", &Person::getAge, &Person::setAge), // access through getter/setter only!
        member("name", &Person::getName, &Person::setName), // same, but ref getter/setter
        member("salary", &Person::salary),
        member("favouriteMovies", &Person::favouriteMovies)
    );
}

template <>
inline auto registerMembers<MovieInfo>()
{
    return members(
        member("name", &MovieInfo::name),
        member("rating", &MovieInfo::rating)
    );
}

}

Note that you can either use pointers to members or pointers to getters/setters. They will be used for doing stuff with members of registered classes. (for reading and setting values).

and now you can call do this:

meta::doForAllMembers<SomeClass>(/* your lambda */);

Your lambda should have one parameter which will be an instance of Member. Calling meta::doForAllMembers<T> gives you ability to do something with each registered member of class T. Inside your lambda you can get member type like this (MemberType = T when decltype(member) = Member<Class, T>): using MemberType = meta::get_member_type<decltype(member)>; (See example/JsonCast.inl for examples of such lambdas).

Some docs (will be better in future!)

Member class has the following functions:

  • const char* getName() - returns const char* of member name you've set during "registration"
  • const T& get(const Class& obj) - gets const reference to the member
  • T getCopy(const Class& obj) - gets copy of member (useful to if only value getter is provided, can't return const T& in that case)
  • void set(const Class& obj, V&& value) - sets value to the member, lvalues and rvalues are accepted
  • T& getRef(const Class& obj) - gets non const reference to the member

In general Meta::getMembers<T>() template function specialization should have a following form and should be put in header with you class (see comments in Meta.h for more info)

It's important for this function to be inline and be defined in header file because the compiler has to figure out return type and you don't want to define the same function in two different compilation units!

namespace meta
{

template <>
inline auto registerMembers<SomeClass>()
{
    return members(
        member(...),
        ...
    );
}

}

You can register members by using their data member pointer:

member("someMember", &SomeClass::someMember)

Or use getters/setters:

member("someMember", &SomeClass::getSomeMember, &SomeClass::setSomeMember)

If you provide Member with getters and setters it will use these functions for getting/setting members, otherwise the member will be accessed directly with pointer to member.

And you can add non-const getter (not necessary):

member(...).addNonConstGetter(&SomeClass::getSomeMemberRef)

Getters and setters can be by-value:

// T is member type
T SomeClass::getSomeMember() const { return someMember; }
void SomeClass::getSomeMember(T value) { someMember = value; }

... or by reference

// T is member type
const T& SomeClass::getSomeMember() const { return someMember; }
void SomeClass::getSomeMember(const T& value) { someMember = value; }

Non-const getter has the following form:

// T is member type
T& SomeClass::getSomeMemberRef() { return someMember; }

Getters and setters are always called (if they're present) in Member::get/set functions, otherwise the pointer to member is used. The same applies to non-const getter in Member::getRef.

You can make the template specialization of registerMembers a friend to your registered class to be able to access and add private members. You can do it like this:

class SomeClass {
    friend auto meta::registerMembers<SomeClass>(); // Visual Studio may produce warning here
        // Just ignore it, it's a bug (`#pragma warning (disable : 4396)` is added in Meta.h
};

Inheritance

If you have a base class registered, you can combine its members tuple with a one from derived class. See this example of how you can do it.

License

This library is licensed under the MIT License, see LICENSE for more information.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].