renamed flexible to brief_syntax

This commit is contained in:
Mindaugas Vinkelis
2019-07-04 14:17:36 +03:00
committed by Mindaugas Vinkelis
parent ff40222124
commit f35ae3f4dc
29 changed files with 240 additions and 297 deletions

View File

@@ -10,6 +10,7 @@
* AdapterWriter/Reader classes, and their functionality is moved to `adapters`.
* UnsafeInputBufferAdapter, instead config option is provided to disable buffer read errors
* isValidState from stream output adapter, because it didn't provide any additional information that couldn't be queried directly on stream object.
* archive from serializer/deserializer
## other breaking changes
@@ -28,6 +29,9 @@
* renamed NetworkEndianness to Endianness in config
* MeasureSize adapter moved to separate file `/adapter/measure_size.h`
* removed Writer/Reader parameter from extensions serialize/deserialize methods
* renamed flexible to brief_syntax,
* folder
* file
## improvements
@@ -46,10 +50,6 @@ e.g. instead of writing `s.container(obj, [](S& s, MyData& data) {s.ext(data, My
## bugfix
* fixed enabledBitPacking where writer and internal context states was not restored properly after exiting from this function
## todo
* flexible syntax, enable option (using config) to use compactvalue for fundamental types by default (it should be off to preserve ABI breaking change).
* rename "flexible" to "brief_syntax"
# [4.6.1](https://github.com/fraillt/bitsery/compare/v4.6.0...v4.6.1) (2019-06-27)
### Features

View File

@@ -4,7 +4,7 @@ Once you're familiar with the library consider the following reference material.
Library design:
* `fundamental types`
* `valueNb instead of value`
* `flexible syntax`
* `brief syntax`
* `serializer/deserializer functions overloads`
* `extending library functionality`
* `errors handling`
@@ -15,9 +15,8 @@ Library design:
Core Serializer/Deserializer functions (alphabetical order):
* `operator()` (4.6.1) (when flexible syntax is enabled)
* `operator()` (4.6.1) (when brief syntax is enabled)
* `adapter` (5.0.0)
* `archive` (4.0.0) (when flexible syntax is enabled)
* `boolValue` (4.0.0)
* `context<T>` (4.1.0)
* `contextOrNull<T>` (4.2.0)

View File

@@ -34,8 +34,8 @@ Now let's review features in more detail.
* **Cross-platform compatible.** if same code compiles on Android, PS3 console, and your PC either x64 or x86 architecture, you are 100% sure it works.
To achieve this, bitsery specifically defines size of underlying data, hence syntax is *value\<2\>* (alias function *value2b*) instead or *value*, or *container2b* for element type of 16bits, eg int16_t.
Bitsery also applies endianness transformation if necessary.
* **Flexible syntax.** If you don't like like writing code with explicitly specifying underlying type size, like *container2b* or *value8b*, you can use flexible syntax.
Just include <bitsery/flexible.h> and can write like in [cereal](http://uscilab.github.io/cereal/).
* **Brief syntax.** If you don't like like writing code with explicitly specifying underlying type size, like *container2b* or *value8b*, you can use brief syntax.
Just include <bitsery/brief_syntax.h> and can write like in [cereal](http://uscilab.github.io/cereal/).
But do it on your own risk, and static assert using *assertFundamentalTypeSizes* function if you're planing to use it across multiple platforms.
* **Optimized for speed and space.** library itself doesn't do any allocations (except if you use backward/forward compatibility) so data writing/reading is fast as memcpy to/from your buffer.
It also doesn't serialize any type information, all information needed is written in your code!

View File

@@ -58,7 +58,7 @@ void serialize(S& s, MyStruct& o) {
**bitsery** also allows to define serialize function in side your class, and can also serialize private class members, just make *friend bitsery::Access;*
**bitsery** supports two ways how to describe your serialization flow: *verbose syntax* (as in example) or *flexible syntax*, similar to *cereal* library, just include `<bitsery/flexible.h>` to use it.
**bitsery** supports two ways how to describe your serialization flow: *verbose syntax* (as in example) or *brief syntax*, similar to *cereal* library, just include `<bitsery/brief_syntax.h>` to use it.
This example we choosed probably unfamiliar verbose syntax, so lets explain core functionality that you'll use all the time:
* **s.value4b(o.i);** serialize fundamental types (ints, floats, enums) value**4b** means, that data type is 4 bytes. If you use same code on different machines, if it compiles it means it is compatible.

View File

@@ -29,11 +29,6 @@ endif()
file(GLOB ExampleFiles ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
if (WIN32)
message(WARNING "Removing example `flexible_assert_linux_x64` for Windows")
list(REMOVE_ITEM ExampleFiles ${CMAKE_CURRENT_SOURCE_DIR}/flexible_assert_linux_x64.cpp)
endif()
foreach(ExampleFile ${ExampleFiles})
get_filename_component(ExampleName ${ExampleFile} NAME_WE)
add_executable(bitsery.example.${ExampleName} ${ExampleFile})

View File

@@ -1,12 +1,12 @@
#include <bitsery/bitsery.h>
#include <bitsery/adapter/buffer.h>
//include flexible header, to use flexible syntax
#include <bitsery/flexible.h>
//to use brief syntax always include this header
#include <bitsery/brief_syntax.h>
//we also need additional traits to work with container types,
//instead of including <bitsery/traits/vector.h> for vector traits, now we also need traits to work with flexible types.
//so include everything from <bitsery/flexible/...> instead of <bitsery/traits/...>
//instead of including <bitsery/traits/vector.h> for vector traits, now we also need traits to work with brief_syntax types.
//so include everything from <bitsery/brief_syntax/...> instead of <bitsery/traits/...>
//otherwise we'll get static assert error, saying to define serialize function.
#include <bitsery/flexible/vector.h>
#include <bitsery/brief_syntax/vector.h>
enum class MyEnum:uint16_t { V1,V2,V3 };
struct MyStruct {
@@ -17,10 +17,8 @@ struct MyStruct {
//define serialize function as usual
template <typename S>
void serialize(S& s) {
//now we can use flexible syntax with
s.archive(i, e, fs);
// flexible syntax also supports `cereal` like serialization interface by calling operator()
// s(i, e, fs);
//now we can use brief syntax with
s(i, e, fs);
}
};

View File

@@ -1,45 +0,0 @@
#include <bitsery/bitsery.h>
#include <bitsery/adapter/buffer.h>
#include <bitsery/flexible.h>
#include <bitsery/flexible/vector.h>
struct MyStruct {
int i;
unsigned short s;
std::vector<long> vl;
long long ll;
template <typename S>
void serialize(S& s) {
//now we can use flexible syntax with
//member function has same name as parameter
s.archive(this->s, i, vl, ll);
}
};
using namespace bitsery;
//some helper types
using Buffer = std::vector<uint8_t>;
using OutputAdapter = OutputBufferAdapter<Buffer>;
using InputAdapter = InputBufferAdapter<Buffer>;
int main() {
//this will only work on linux or mac x64
bitsery::assertFundamentalTypeSizes<2,4,8,8>();
//set some random data
MyStruct data{8941, 3, {15l, -8l, 045l}, 8459845ll};
MyStruct res{};
//serialization, deserialization flow is unchanged as in basic usage
Buffer buffer;
auto writtenSize = quickSerialization<OutputAdapter>(buffer, data);
auto state = quickDeserialization<InputAdapter>({buffer.begin(), writtenSize}, res);
assert(state.first == ReaderError::NoError && state.second);
assert(data.vl == res.vl && data.s == res.s && data.i == res.i && data.ll == res.ll);
}

View File

@@ -21,35 +21,35 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_H
#define BITSERY_FLEXIBLE_H
#ifndef BITSERY_BRIEF_SYNTAX_H
#define BITSERY_BRIEF_SYNTAX_H
#include "details/serialization_common.h"
#include "details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
//define function that enables s.archive(....) usage
//define function that enables s(....) usage
template<typename S, typename T>
void archiveProcess(S& s, T&& head) {
static_assert(std::is_lvalue_reference<T>::value || std::is_base_of<flexible::ArchiveWrapperFnc, T>::value,
"Argument must be either lvalue or subclass of flexible::ArchiveWrapperFnc");
void processBriefSyntax(S& s, T&& head) {
static_assert(std::is_lvalue_reference<T>::value || std::is_base_of<brief_syntax::ModFnc, T>::value,
"Argument must be either lvalue or subclass of brief_syntax::ModFnc");
s.object(head);
}
//wrapper functions that enables to serialize as container or string
template<typename T, size_t N>
flexible::CArray<T, N, true> asText(T (& str)[N]) {
brief_syntax::CArray<T, N, true> asText(T (& str)[N]) {
return {str};
}
template<typename T, size_t N>
flexible::CArray<T, N, false> asContainer(T (& obj)[N]) {
brief_syntax::CArray<T, N, false> asContainer(T (& obj)[N]) {
return {obj};
}
template<typename T>
flexible::MaxSize<T> maxSize(T& obj, size_t max) {
brief_syntax::MaxSize<T> maxSize(T& obj, size_t max) {
return {obj, max};
}
@@ -75,7 +75,7 @@ namespace bitsery {
template<typename S, typename T, size_t N, typename std::enable_if<!std::is_integral<T>::value>::type * = nullptr>
void serialize(S& s, T (& obj)[N]) {
flexible::processContainer(s, obj);
brief_syntax::processContainer(s, obj);
}
//this is a helper class that enforce fundamental type sizes, when used on multiple platforms
@@ -91,4 +91,4 @@ namespace bitsery {
}
#endif //BITSERY_FLEXIBLE_H
#endif //BITSERY_BRIEF_SYNTAX_H

View File

@@ -21,17 +21,17 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_ARRAY_H
#define BITSERY_FLEXIBLE_TYPE_STD_ARRAY_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_ARRAY_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_ARRAY_H
#include "../traits/array.h"
#include "../details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
template<typename S, typename T, size_t N>
void serialize(S &s, std::array<T, N> &obj) {
flexible::processContainer(s, obj);
brief_syntax::processContainer(s, obj);
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_ARRAY_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_ARRAY_H

View File

@@ -20,8 +20,8 @@
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_CHRONO_H
#define BITSERY_FLEXIBLE_TYPE_STD_CHRONO_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_CHRONO_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_CHRONO_H
#include "../ext/std_chrono.h"
@@ -37,4 +37,4 @@ namespace bitsery {
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_CHRONO_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_CHRONO_H

View File

@@ -21,17 +21,17 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_DEQUE_H
#define BITSERY_FLEXIBLE_TYPE_STD_DEQUE_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_DEQUE_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_DEQUE_H
#include "../traits/deque.h"
#include "../details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
template<typename S, typename T, typename Allocator>
void serialize(S &s, std::deque<T, Allocator> &obj) {
flexible::processContainer(s, obj);
brief_syntax::processContainer(s, obj);
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_DEQUE_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_DEQUE_H

View File

@@ -21,17 +21,17 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_FORWARD_LIST_H
#define BITSERY_FLEXIBLE_TYPE_STD_FORWARD_LIST_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_FORWARD_LIST_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_FORWARD_LIST_H
#include "../traits/forward_list.h"
#include "../details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
template<typename S, typename T, typename Allocator>
void serialize(S &s, std::forward_list<T, Allocator> &obj) {
flexible::processContainer(s, obj);
brief_syntax::processContainer(s, obj);
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_FORWARD_LIST_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_FORWARD_LIST_H

View File

@@ -21,17 +21,17 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_LIST_H
#define BITSERY_FLEXIBLE_TYPE_STD_LIST_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_LIST_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_LIST_H
#include "../traits/list.h"
#include "../details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
template<typename S, typename T, typename Allocator>
void serialize(S &s, std::list<T, Allocator> &obj) {
flexible::processContainer(s, obj);
brief_syntax::processContainer(s, obj);
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_LIST_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_LIST_H

View File

@@ -21,8 +21,8 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_MAP_H
#define BITSERY_FLEXIBLE_TYPE_STD_MAP_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_MAP_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_MAP_H
#include <map>
#include "../ext/std_map.h"
@@ -47,4 +47,4 @@ namespace bitsery {
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_MAP_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_MAP_H

View File

@@ -20,8 +20,8 @@
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_MEMORY_H
#define BITSERY_FLEXIBLE_TYPE_STD_MEMORY_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_MEMORY_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_MEMORY_H
#include "../ext/std_smart_ptr.h"
@@ -42,4 +42,4 @@ namespace bitsery {
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_MEMORY_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_MEMORY_H

View File

@@ -21,8 +21,8 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_QUEUE_H
#define BITSERY_FLEXIBLE_TYPE_STD_QUEUE_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_QUEUE_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_QUEUE_H
#include "../ext/std_queue.h"
@@ -39,4 +39,4 @@ namespace bitsery {
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_QUEUE_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_QUEUE_H

View File

@@ -21,8 +21,8 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_SET_H
#define BITSERY_FLEXIBLE_TYPE_STD_SET_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_SET_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_SET_H
#include <set>
#include "../ext/std_set.h"
@@ -40,4 +40,4 @@ namespace bitsery {
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_SET_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_SET_H

View File

@@ -21,8 +21,8 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_STACK_H
#define BITSERY_FLEXIBLE_TYPE_STD_STACK_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_STACK_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_STACK_H
#include "../ext/std_stack.h"
@@ -33,4 +33,4 @@ namespace bitsery {
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_STACK_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_STACK_H

View File

@@ -21,17 +21,17 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_STRING_H
#define BITSERY_FLEXIBLE_TYPE_STD_STRING_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_STRING_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_STRING_H
#include "../traits/string.h"
#include "../details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
template<typename S, typename CharT, typename Traits, typename Allocator>
void serialize(S &s, std::basic_string<CharT, Traits, Allocator> &str) {
flexible::processContainer(s, str);
brief_syntax::processContainer(s, str);
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_STRING_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_STRING_H

View File

@@ -20,8 +20,8 @@
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_TUPLE_H
#define BITSERY_FLEXIBLE_TYPE_STD_TUPLE_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_TUPLE_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_TUPLE_H
#include "../ext/std_tuple.h"
@@ -32,4 +32,4 @@ namespace bitsery {
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_TUPLE_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_TUPLE_H

View File

@@ -21,8 +21,8 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_UNORDERED_MAP_H
#define BITSERY_FLEXIBLE_TYPE_STD_UNORDERED_MAP_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_UNORDERED_MAP_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_UNORDERED_MAP_H
#include <unordered_map>
#include "../ext/std_map.h"
@@ -48,4 +48,4 @@ namespace bitsery {
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_UNORDERED_MAP_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_UNORDERED_MAP_H

View File

@@ -21,8 +21,8 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_UNORDERED_SET_H
#define BITSERY_FLEXIBLE_TYPE_STD_UNORDERED_SET_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_UNORDERED_SET_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_UNORDERED_SET_H
#include <unordered_set>
#include "../ext/std_set.h"
@@ -40,4 +40,4 @@ namespace bitsery {
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_UNORDERED_SET_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_UNORDERED_SET_H

View File

@@ -20,8 +20,8 @@
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_VARIANT_H
#define BITSERY_FLEXIBLE_TYPE_STD_VARIANT_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_VARIANT_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_VARIANT_H
#include "../ext/std_variant.h"
@@ -32,4 +32,4 @@ namespace bitsery {
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_VARIANT_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_VARIANT_H

View File

@@ -21,17 +21,17 @@
//SOFTWARE.
#ifndef BITSERY_FLEXIBLE_TYPE_STD_VECTOR_H
#define BITSERY_FLEXIBLE_TYPE_STD_VECTOR_H
#ifndef BITSERY_BRIEF_SYNTAX_TYPE_STD_VECTOR_H
#define BITSERY_BRIEF_SYNTAX_TYPE_STD_VECTOR_H
#include "../traits/vector.h"
#include "../details/flexible_common.h"
#include "bitsery/details/brief_syntax_common.h"
namespace bitsery {
template<typename S, typename T, typename Allocator>
void serialize(S &s, std::vector<T, Allocator> &obj) {
flexible::processContainer(s, obj);
brief_syntax::processContainer(s, obj);
}
}
#endif //BITSERY_FLEXIBLE_TYPE_STD_VECTOR_H
#endif //BITSERY_BRIEF_SYNTAX_TYPE_STD_VECTOR_H

View File

@@ -189,20 +189,10 @@ namespace bitsery {
/*
* functionality, that enables simpler serialization syntax, by including additional header
*/
template<typename T, typename ... TArgs>
void archive(T &&head, TArgs &&... tail) {
//serialize object
details::ArchiveFunction<BasicDeserializer, T>::invoke(*this, std::forward<T>(head));
//expand other elements
archive(std::forward<TArgs>(tail)...);
}
template <typename T, typename... TArgs>
BasicDeserializer &operator()(T &&head, TArgs &&... tail) {
//serialize object
details::ArchiveFunction<BasicDeserializer, T>::invoke(*this, std::forward<T>(head));
//expand other elements
archive(std::forward<TArgs>(tail)...);
template <typename... TArgs>
BasicDeserializer &operator()(TArgs &&... args) {
archive(std::forward<TArgs>(args)...);
return *this;
}
@@ -536,6 +526,14 @@ namespace bitsery {
}
template<typename T, typename ... TArgs>
void archive(T &&head, TArgs &&... tail) {
//serialize object
details::BriefSyntaxFunction<BasicDeserializer, T>::invoke(*this, std::forward<T>(head));
//expand other elements
archive(std::forward<TArgs>(tail)...);
}
//dummy function, that stops archive variadic arguments expansion
void archive() {
}

View File

@@ -20,14 +20,14 @@
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#ifndef BITSERY_DETAILS_FLEXIBLE_COMMON_H
#define BITSERY_DETAILS_FLEXIBLE_COMMON_H
#ifndef BITSERY_DETAILS_BRIEF_SYNTAX_COMMON_H
#define BITSERY_DETAILS_BRIEF_SYNTAX_COMMON_H
#include "../traits/core/traits.h"
#include <limits>
namespace bitsery {
namespace flexible {
namespace brief_syntax {
//these function overloads is required to apply maxSize, and optimize for fundamental types
//for contigous arrays of fundamenal types, memcpy will be applied
@@ -84,13 +84,13 @@ namespace bitsery {
//all wrapper functions, that modify behaviour, should inherit from this
struct ArchiveWrapperFnc {
struct ModFnc {
};
//this type is used to differentiate between container and text behaviour
template<typename T, size_t N, bool isText>
struct CArray : public ArchiveWrapperFnc {
struct CArray : public ModFnc {
CArray(T (&data_)[N]) : data{data_} {};
T (&data)[N];
};
@@ -107,7 +107,7 @@ namespace bitsery {
//used to set max container size
template<typename T>
struct MaxSize : public ArchiveWrapperFnc {
struct MaxSize : public ModFnc {
MaxSize(T &data_, size_t maxSize_) : data{data_}, maxSize{maxSize_} {};
T &data;
size_t maxSize;
@@ -146,4 +146,4 @@ namespace bitsery {
}
}
#endif //BITSERY_DETAILS_FLEXIBLE_COMMON_H
#endif //BITSERY_DETAILS_BRIEF_SYNTAX_COMMON_H

View File

@@ -143,20 +143,20 @@ namespace bitsery {
template <typename S, typename T>
struct HasSerializeMethod :HasSerializeMethodHelper<S, T>::type {};
//helper types for IsFlexibleIncluded
//helper types for IsBriefSyntaxIncluded
template <typename S, typename T>
using TryArchiveProcess = decltype(archiveProcess(std::declval<S &>(), std::declval<T &&>()));
using TryProcessBriefSyntax = decltype(processBriefSyntax(std::declval<S &>(), std::declval<T &&>()));
template <typename S, typename T>
struct IsFlexibleIncludedHelper {
template <typename Q, typename R, typename = TryArchiveProcess<Q, R>>
struct IsBriefSyntaxIncludedHelper {
template <typename Q, typename R, typename = TryProcessBriefSyntax<Q, R>>
static std::true_type tester(Q&&, R&&);
static std::false_type tester(...);
using type = decltype(tester(std::declval<S>(), std::declval<T>()));
};
template <typename S, typename T>
struct IsFlexibleIncluded :IsFlexibleIncludedHelper<S, T>::type {};
struct IsBriefSyntaxIncluded :IsBriefSyntaxIncludedHelper<S, T>::type {};
#else
//helper metafunction, that is added to c++17
template<typename... Ts>
@@ -189,12 +189,12 @@ namespace bitsery {
//this solution doesn't work with visual studio, but is more elegant
template<typename, typename, typename = void>
struct IsFlexibleIncluded : std::false_type {
struct IsBriefSyntaxIncluded : std::false_type {
};
template<typename S, typename T>
struct IsFlexibleIncluded<S, T,
void_t<decltype(archiveProcess(std::declval<S &>(), std::declval<T &&>()))>
struct IsBriefSyntaxIncluded<S, T,
void_t<decltype(processBriefSyntax(std::declval<S &>(), std::declval<T &&>()))>
> : std::true_type {
};
#endif
@@ -286,13 +286,13 @@ namespace bitsery {
*/
template<typename S, typename T, typename Enabled = void>
struct ArchiveFunction {
struct BriefSyntaxFunction {
static void invoke(S &s, T &&obj) {
static_assert(IsFlexibleIncluded<S, T>::value,
"\nPlease include '<bitsery/flexible.h>' to use 'archive' function:\n");
static_assert(IsBriefSyntaxIncluded<S, T>::value,
"\nPlease include '<bitsery/brief_syntax.h>' to use operator():\n");
archiveProcess(s, std::forward<T>(obj));
processBriefSyntax(s, std::forward<T>(obj));
}
};

View File

@@ -186,18 +186,10 @@ namespace bitsery {
/*
* functionality, that enables simpler serialization syntax, by including additional header
*/
template<typename T, typename ... TArgs>
void archive(T &&head, TArgs &&... tail) {
//serialize object
details::ArchiveFunction<BasicSerializer, T>::invoke(*this, std::forward<T>(head));
//expand other elements
archive(std::forward<TArgs>(tail)...);
}
template <typename T, typename... TArgs>
BasicSerializer &operator()(T &&head, TArgs &&... tail) {
details::ArchiveFunction<BasicSerializer, T>::invoke(*this, std::forward<T>(head));
archive(std::forward<TArgs>(tail)...);
template <typename... TArgs>
BasicSerializer &operator()(TArgs &&... args) {
archive(std::forward<TArgs>(args)...);
return *this;
}
@@ -513,6 +505,13 @@ namespace bitsery {
}
template<typename T, typename ... TArgs>
void archive(T &&head, TArgs &&... tail) {
//serialize object
details::BriefSyntaxFunction<BasicSerializer, T>::invoke(*this, std::forward<T>(head));
//expand other elements
archive(std::forward<TArgs>(tail)...);
}
//dummy function, that stops archive variadic arguments expansion
void archive() {
}

View File

@@ -20,25 +20,24 @@
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#include <bitsery/flexible.h>
#include <bitsery/flexible/string.h>
#include <bitsery/flexible/array.h>
#include <bitsery/flexible/vector.h>
#include <bitsery/flexible/list.h>
#include <bitsery/flexible/forward_list.h>
#include <bitsery/flexible/deque.h>
#include <bitsery/flexible/queue.h>
#include <bitsery/flexible/stack.h>
#include <bitsery/flexible/map.h>
#include <bitsery/flexible/unordered_map.h>
#include <bitsery/flexible/set.h>
#include <bitsery/flexible/unordered_set.h>
#include <bitsery/flexible/memory.h>
#include <bitsery/flexible/chrono.h>
#include <bitsery/brief_syntax.h>
#include <bitsery/brief_syntax/array.h>
#include <bitsery/brief_syntax/chrono.h>
#include <bitsery/brief_syntax/deque.h>
#include <bitsery/brief_syntax/forward_list.h>
#include <bitsery/brief_syntax/list.h>
#include <bitsery/brief_syntax/map.h>
#include <bitsery/brief_syntax/memory.h>
#include <bitsery/brief_syntax/queue.h>
#include <bitsery/brief_syntax/set.h>
#include <bitsery/brief_syntax/stack.h>
#include <bitsery/brief_syntax/string.h>
#include <bitsery/brief_syntax/unordered_map.h>
#include <bitsery/brief_syntax/unordered_set.h>
#include <bitsery/brief_syntax/vector.h>
#if __cplusplus > 201402L
#include <bitsery/flexible/tuple.h>
#include <bitsery/flexible/variant.h>
#include <bitsery/brief_syntax/tuple.h>
#include <bitsery/brief_syntax/variant.h>
#else
#if defined(_MSC_VER)
#pragma message("tuple and variant only works with c++17")
@@ -52,14 +51,14 @@
using testing::Eq;
TEST(FlexibleSyntax, FundamentalTypesAndBool) {
TEST(BriefSyntax, FundamentalTypesAndBool) {
int ti = 8745;
MyEnumClass te = MyEnumClass::E4;
float tf = 485.042f;
double td = -454184.48445;
bool tb = true;
SerializationContext ctx{};
ctx.createSerializer().archive(ti, te, tf, td, tb);
ctx.createSerializer()(ti, te, tf, td, tb);
//result
int ri{};
@@ -67,7 +66,7 @@ TEST(FlexibleSyntax, FundamentalTypesAndBool) {
float rf{};
double rd{};
bool rb{};
ctx.createDeserializer().archive(ri, re, rf, rd, rb);
ctx.createDeserializer()(ri, re, rf, rd, rb);
//test
EXPECT_THAT(ri, Eq(ti));
@@ -77,7 +76,7 @@ TEST(FlexibleSyntax, FundamentalTypesAndBool) {
EXPECT_THAT(rb, Eq(tb));
}
TEST(FlexibleSyntax, UseObjectFncInsteadOfValueN) {
TEST(BriefSyntax, UseObjectFncInsteadOfValueN) {
int ti = 8745;
MyEnumClass te = MyEnumClass::E4;
float tf = 485.042f;
@@ -112,7 +111,7 @@ TEST(FlexibleSyntax, UseObjectFncInsteadOfValueN) {
EXPECT_THAT(rb, Eq(tb));
}
TEST(FlexibleSyntax, MixDifferentSyntax) {
TEST(BriefSyntax, MixDifferentSyntax) {
int ti = 8745;
MyEnumClass te = MyEnumClass::E4;
float tf = 485.042f;
@@ -121,7 +120,7 @@ TEST(FlexibleSyntax, MixDifferentSyntax) {
SerializationContext ctx;
auto& ser = ctx.createSerializer();
ser.value<sizeof(ti)>(ti);
ser.archive(te, tf, td);
ser(te, tf, td);
ser.object(tb);
//result
@@ -131,7 +130,7 @@ TEST(FlexibleSyntax, MixDifferentSyntax) {
double rd{};
bool rb{};
auto& des = ctx.createDeserializer();
des.archive(ri, re, rf);
des(ri, re, rf);
des.value8b(rd);
des.object(rb);
@@ -144,130 +143,130 @@ TEST(FlexibleSyntax, MixDifferentSyntax) {
}
template<typename T>
T procArchive(const T& testData) {
T procBriefSyntax(const T& testData) {
SerializationContext ctx;
ctx.createSerializer().archive(testData);
ctx.createSerializer()(testData);
T res{};
ctx.createDeserializer().archive(res);
ctx.createDeserializer()(res);
return res;
}
template<typename T>
T procArchiveWithMaxSize(const T& testData) {
T procBriefSyntaxWithMaxSize(const T& testData) {
SerializationContext ctx;
ctx.createSerializer().archive(bitsery::maxSize(testData, 100));
ctx.createSerializer()(bitsery::maxSize(testData, 100));
T res{};
ctx.createDeserializer().archive(bitsery::maxSize(res, 100));
ctx.createDeserializer()(bitsery::maxSize(res, 100));
return res;
}
TEST(FlexibleSyntax, CStyleArrayForValueTypesAsContainer) {
TEST(BriefSyntax, CStyleArrayForValueTypesAsContainer) {
const int t1[3]{8748, -484, 45};
int r1[3]{0, 0, 0};
SerializationContext ctx;
ctx.createSerializer().archive(bitsery::asContainer(t1));
ctx.createDeserializer().archive(bitsery::asContainer(r1));
ctx.createSerializer()(bitsery::asContainer(t1));
ctx.createDeserializer()(bitsery::asContainer(r1));
EXPECT_THAT(r1, ::testing::ContainerEq(t1));
}
TEST(FlexibleSyntax, CStyleArrayForIntegralTypesAsText) {
TEST(BriefSyntax, CStyleArrayForIntegralTypesAsText) {
const char t1[3]{"hi"};
char r1[3]{0, 0, 0};
SerializationContext ctx;
ctx.createSerializer().archive(bitsery::asText(t1));
ctx.createDeserializer().archive(bitsery::asText(r1));
ctx.createSerializer()(bitsery::asText(t1));
ctx.createDeserializer()(bitsery::asText(r1));
EXPECT_THAT(r1, ::testing::ContainerEq(t1));
}
TEST(FlexibleSyntax, CStyleArray) {
TEST(BriefSyntax, CStyleArray) {
const MyEnumClass t1[3]{MyEnumClass::E1, MyEnumClass::E4, MyEnumClass::E2};
MyEnumClass r1[3]{};
SerializationContext ctx;
ctx.createSerializer().archive(t1);
ctx.createDeserializer().archive(r1);
ctx.createSerializer()(t1);
ctx.createDeserializer()(r1);
EXPECT_THAT(r1, ::testing::ContainerEq(t1));
}
TEST(FlexibleSyntax, StdString) {
TEST(BriefSyntax, StdString) {
std::string t1{"my nice string"};
std::string t2{};
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t2), Eq(t2));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t2), Eq(t2));
}
TEST(FlexibleSyntax, StdArray) {
TEST(BriefSyntax, StdArray) {
std::array<int, 3> t1{8748, -484, 45};
std::array<int, 0> t2{};
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t2), Eq(t2));
}
TEST(FlexibleSyntax, StdVector) {
TEST(BriefSyntax, StdVector) {
std::vector<int> t1{8748, -484, 45};
std::vector<float> t2{5.f, 0.198f};
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t2), Eq(t2));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t2), Eq(t2));
}
TEST(FlexibleSyntax, StdList) {
TEST(BriefSyntax, StdList) {
std::list<int> t1{8748, -484, 45};
std::list<float> t2{5.f, 0.198f};
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t2), Eq(t2));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t2), Eq(t2));
}
TEST(FlexibleSyntax, StdForwardList) {
TEST(BriefSyntax, StdForwardList) {
std::forward_list<int> t1{8748, -484, 45};
std::forward_list<float> t2{5.f, 0.198f};
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t2), Eq(t2));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t2), Eq(t2));
}
TEST(FlexibleSyntax, StdDeque) {
TEST(BriefSyntax, StdDeque) {
std::deque<int> t1{8748, -484, 45};
std::deque<float> t2{5.f, 0.198f};
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t2), Eq(t2));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t2), Eq(t2));
}
TEST(FlexibleSyntax, StdQueue) {
TEST(BriefSyntax, StdQueue) {
std::queue<std::string> t1;
t1.push("first");
t1.push("second string");
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
}
TEST(FlexibleSyntax, StdPriorityQueue) {
TEST(BriefSyntax, StdPriorityQueue) {
std::priority_queue<std::string> t1;
t1.push("first");
t1.push("second string");
t1.push("third");
t1.push("fourth");
auto r1 = procArchive(t1);
auto r1 = procBriefSyntax(t1);
//we cannot compare priority queue directly
EXPECT_THAT(r1.size(), Eq(t1.size()));
@@ -278,50 +277,50 @@ TEST(FlexibleSyntax, StdPriorityQueue) {
}
}
TEST(FlexibleSyntax, StdStack) {
TEST(BriefSyntax, StdStack) {
std::stack<std::string> t1;
t1.push("first");
t1.push("second string");
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
}
TEST(FlexibleSyntax, StdUnorderedMap) {
TEST(BriefSyntax, StdUnorderedMap) {
std::unordered_map<int, int> t1;
t1.emplace(3423, 624);
t1.emplace(-5484, -845);
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
}
TEST(FlexibleSyntax, StdUnorderedMultiMap) {
TEST(BriefSyntax, StdUnorderedMultiMap) {
std::unordered_multimap<std::string, int> t1;
t1.emplace("one", 624);
t1.emplace("two", -845);
t1.emplace("one", 897);
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
EXPECT_TRUE(procBriefSyntaxWithMaxSize(t1) == t1);
}
TEST(FlexibleSyntax, StdMap) {
TEST(BriefSyntax, StdMap) {
std::map<int, int> t1;
t1.emplace(3423, 624);
t1.emplace(-5484, -845);
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
}
TEST(FlexibleSyntax, StdMultiMap) {
TEST(BriefSyntax, StdMultiMap) {
std::multimap<std::string, int> t1;
t1.emplace("one", 624);
t1.emplace("two", -845);
t1.emplace("one", 897);
auto res = procArchive(t1);
auto res = procBriefSyntax(t1);
//same key values is not ordered, and operator == compares each element at same position
//so we need to compare our selves
EXPECT_THAT(res.size(), Eq(3));
@@ -334,38 +333,38 @@ TEST(FlexibleSyntax, StdMultiMap) {
}
}
TEST(FlexibleSyntax, StdUnorderedSet) {
TEST(BriefSyntax, StdUnorderedSet) {
std::unordered_set<std::string> t1;
t1.emplace("one");
t1.emplace("two");
t1.emplace("three");
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
EXPECT_TRUE(procBriefSyntaxWithMaxSize(t1) == t1);
}
TEST(FlexibleSyntax, StdUnorderedMultiSet) {
TEST(BriefSyntax, StdUnorderedMultiSet) {
std::unordered_multiset<std::string> t1;
t1.emplace("one");
t1.emplace("two");
t1.emplace("three");
t1.emplace("one");
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
EXPECT_TRUE(procBriefSyntaxWithMaxSize(t1) == t1);
}
TEST(FlexibleSyntax, StdSet) {
TEST(BriefSyntax, StdSet) {
std::set<std::string> t1;
t1.emplace("one");
t1.emplace("two");
t1.emplace("three");
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
EXPECT_TRUE(procBriefSyntaxWithMaxSize(t1) == t1);
}
TEST(FlexibleSyntax, StdMultiSet) {
TEST(BriefSyntax, StdMultiSet) {
std::multiset<std::string> t1;
t1.emplace("one");
t1.emplace("two");
@@ -373,23 +372,23 @@ TEST(FlexibleSyntax, StdMultiSet) {
t1.emplace("one");
t1.emplace("two");
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
EXPECT_TRUE(procBriefSyntaxWithMaxSize(t1) == t1);
}
TEST(FlexibleSyntax, StdSmartPtr) {
TEST(BriefSyntax, StdSmartPtr) {
std::shared_ptr<int> dataShared1(new int{4});
std::weak_ptr<int> dataWeak1(dataShared1);
std::unique_ptr<std::string> dataUnique1{new std::string{"hello world"}};
bitsery::ext::PointerLinkingContext plctx1{};
BasicSerializationContext<bitsery::ext::PointerLinkingContext> ctx;
ctx.createSerializer(plctx1).archive(dataShared1, dataWeak1, dataUnique1);
ctx.createSerializer(plctx1)(dataShared1, dataWeak1, dataUnique1);
std::shared_ptr<int> resShared1{};
std::weak_ptr<int> resWeak1{};
std::unique_ptr<std::string> resUnique1{};
ctx.createDeserializer(plctx1).archive(resShared1, resWeak1, resUnique1);
ctx.createDeserializer(plctx1)(resShared1, resWeak1, resUnique1);
//clear shared state from pointer linking context
plctx1.clearSharedState();
@@ -399,38 +398,38 @@ TEST(FlexibleSyntax, StdSmartPtr) {
EXPECT_THAT(*resUnique1, Eq(*dataUnique1));
}
TEST(FlexibleSyntax, StdDuration) {
TEST(BriefSyntax, StdDuration) {
std::chrono::duration<int64_t, std::milli> t1{54654};
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
}
TEST(FlexibleSyntax, StdTimePoint) {
TEST(BriefSyntax, StdTimePoint) {
using Duration = std::chrono::duration<double, std::milli>;
using TP = std::chrono::time_point<std::chrono::system_clock, Duration>;
TP data{Duration{874656.4798}};
EXPECT_TRUE(procArchive(data) == data);
EXPECT_TRUE(procBriefSyntax(data) == data);
}
#if __cplusplus > 201402L
TEST(FlexibleSyntax, StdTuple) {
TEST(BriefSyntax, StdTuple) {
std::tuple<int, std::string, std::vector<char>> t1{5,"hello hello", {'A','B','C'}};
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
}
TEST(FlexibleSyntax, StdVariant) {
TEST(BriefSyntax, StdVariant) {
std::variant<float, std::string, std::chrono::milliseconds> t1{std::string("hello hello")};
EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procBriefSyntax(t1) == t1);
}
#endif
TEST(FlexibleSyntax, NestedTypes) {
TEST(BriefSyntax, NestedTypes) {
std::unordered_map<std::string, std::vector<std::string>> t1;
t1.emplace("my key", std::vector<std::string>{"very", "nice", "string"});
t1.emplace("other key", std::vector<std::string>{"just a string"});
EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procBriefSyntax(t1), Eq(t1));
EXPECT_THAT(procBriefSyntaxWithMaxSize(t1), Eq(t1));
}