https://github.com/georgiifirsov/podserializer
Library used to serialize and deserialize any POD-structure (and some non-POD structs) with no modifications applied to them. Here I use a lot of templates and other meta-magic :)
https://github.com/georgiifirsov/podserializer
cplusplus cplusplus-14 cpp cpp14 pods serialization templates
Last synced: 15 days ago
JSON representation
Library used to serialize and deserialize any POD-structure (and some non-POD structs) with no modifications applied to them. Here I use a lot of templates and other meta-magic :)
- Host: GitHub
- URL: https://github.com/georgiifirsov/podserializer
- Owner: GeorgiiFirsov
- License: gpl-3.0
- Created: 2020-02-04T20:00:36.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2021-04-17T16:44:49.000Z (about 4 years ago)
- Last Synced: 2025-02-16T04:29:07.091Z (2 months ago)
- Topics: cplusplus, cplusplus-14, cpp, cpp14, pods, serialization, templates
- Language: C++
- Homepage: https://georgyfirsov.github.io/articles/cpp_reflection.html
- Size: 184 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# PodSerializer
| Compiler | Version | Status | Comments |
|----------|---------|--------------------|------------------------------------------------------------------------|
| MSVC | 19.22 | [![Success][]]() | Main build system. |
| MSVC | 19.16 | [![Partial][]]() | Precise reflection doesn't work on MSVC 19.16 |
| GCC | 6.1 | [![Partial][]]() | `GetFieldsCount`, `FromTuple` and `GetTypeList` are compiled and tested successfully. |
| CLang | 6.0.0 | [![Partial][]]() | `GetFieldsCount` and `FromTuple` are compiled and tested successfully. |[Success]: https://img.shields.io/badge/Build%20Status-pass-success
[Partial]: https://img.shields.io/badge/Build%20Status-partially%20passed-important
[Failed]: https://img.shields.io/badge/Build%20Status-fail-critical
[NotTested]: https://img.shields.io/badge/Build%20Status-not%20built%20yet-inactivePodSerializer is actually two-in-one library: it contains various static reflection tools along with classes for serialization of POD's.
Now it is possible to serialize some non-POD's into `StringStreamSerializer`. Also you can convert them into a tuple with `ToTuplePrecise` and `ToStandardTuplePrecise` methods.> Developing in progress
> Documentation in progress
## Brief introduction and review
### SerializationCurrently are fully developed two ways to serialize POD's: to binary buffer and to I/O streams. Main featores of serialization tools from this library can be included with `Serialization.h` and `StreamOperators.h` files. Here is an example:
```cpp
struct MyStruct
{
char field1;
int field2;
};// ...
MyStruct original{ 'a', 42 };
MyStruct loaded{ '\0', 0 };BinarySerializer serializer; // Serializer class (it is a specialization of generic template)
BinaryBuffer buffer; // Buffer instance to hold serialized valueserializer.Serialize( original, buffer ); // Save our struct
assert( !buffer.IsEmpty() ); // Here buffer will never be empty
serializer.Deserialize( loaded, buffer ); // Now load data into a new variable
assert( original.field1 == loaded.field1 ); // Ensure equality of fields of loaded and original structs
assert( original.field2 == loaded.field2 );
```Serialization to I/O streams differs from example above only by usage of classes `StringStreamSerializer` and `StringStreamBuffer` instead of `BinarySerializer` and `BinaryBuffer` respectively.
Moreover now you are allowed to write the following code:
```cpp
#include "StreamOperators.h"using namespace io_operators;
// ...
// No operators << and >> are defined for MyStruct!!!
MyStruct obj{ 'a', 42 };std::cout << obj; // Will print "a 42"
std::cin >> obj; // Input each field from keyboard and put them directly into 'obj'
```### Reflection
Another half of th library contains several reflection tools. All of them can be included with file `Reflection.h`. Using this header you can now look inside of some POD structure and, for instance, enumerate each its field (I wish I could find out names of fields... But today it is impossible in C++). Here is a couple examples:
##### Example #1
```cpp
#include "Reflection.h"using namespace io_operators;
struct MyStruct
{
int field1;
double field2;
char field3;
};// ...
MyStruct obj{ 42, 3.14, 'a' };
std::cout << "MyStruct has " // Will print "MyStruct has 3 fields"
<< reflection::GetFieldsCount( obj )
<< " fields" << std::endl;
```##### Example #2
```cpp
#include "Reflection.h"
#include "Tuple.h" // Here is rewritten tuple class and some tools for it// ...
MyStruct obj{ 42, 3.14, 'a' };
// Convert our struct into a tuple
auto tpl = reflection::ToTuple( obj ); // tpl is instance of type types::Tupleassert( types::get<0>( tpl ) == obj.field1 ); // Tuple contains exactly the same values as 'obj'
assert( types::get<1>( tpl ) == obj.field2 );
assert( types::get<2>( tpl ) == obj.field3 );// Will be printed: "42 3.14 a"
// It is really important to use a generic lambda (with template invocation function) inside types::for_each
types::for_each( tpl, []( const auto& elem ) {
std::cout << elem << " ";
});
```##### Example #3
```cpp
#include#include "Reflection.h"
#include "Tuple.h"// ...
MyStruct obj{ 42, 3.14, 'a' };
// You can convert your struct into a standard tuple
auto tpl = reflection::ToStandardTuple( obj ); // tpl is instance of type std::tupleassert( std::get<0>( tpl ) == obj.field1 ); // Tuple contains exactly the same values as 'obj'
assert( std::get<1>( tpl ) == obj.field2 );
assert( std::get<2>( tpl ) == obj.field3 );//
// Moreover you can use ToStdTuple function to convert types::Typle into corresponding std::tuple
//
```##### Example #4
```cpp
#include "Reflection.h"
#include "Tuple.h"// ...
MyStruct obj{ 42, 2.71, 'a' };
types::Tuple tpl{ -42, 2.71, 'b' };// Load values from tuple directly into 'obj'
obj = reflection::FromTuple( tpl );assert( obj.field1 == -42 ); // 'obj' now contains exactly the same values as tuple
assert( obj.field2 == 2.71 );
assert( obj.field3 == 'b' );
```##### Example #5
```cpp
#include "StreamOperators.h"
#include "Reflection.h"
#include "Tuple.h"using namespace io_operators;
struct Person
{
std::string m_name;
size_t m_age;
};// ...
Person bob{ "Bob", 45 };
std::cout << bob; // will print: Bob 45
std::cout << beautiful_struct << bob; // will print: { Bob, 45 }auto bob_tpl = ToTuplePrecise( bob );
// Will print: Bob is 45 years old.
std::cout << types::get<0>( bob_tpl ) << " is "
<< types::get<1>( bob_tpl ) << " years old." << std::endl;
```## Requirements
- C++14 support.
- Reflected (serialization uses reflection inside) structure must not contain static fields (they are simply ignored), bit-fields (they can cause some errors), unions and references. *Currently* pointers are not supported too (coming soon).
- Reflected struct must be constexpr aggregate initializable.
- Other limitations are listed in file [Support.h](https://github.com/GeorgyFirsov/PodSerializer/blob/master/PodSerializer/Support.h)## License
[GNU General Public License v3.0](https://github.com/GeorgyFirsov/PodSerializer/blob/master/LICENSE)