maxSize archive modifying function now works with extensions

This commit is contained in:
fraillt
2017-10-13 09:33:56 +03:00
parent f3c9a33849
commit 4ccd4d368e
18 changed files with 365 additions and 41 deletions

View File

@@ -1,4 +1,4 @@
# [4.0.0](https://github.com/fraillt/bitsery/compare/v3.0.0...v4.0.0) (2017-10-02) # [4.0.0](https://github.com/fraillt/bitsery/compare/v3.0.0...v4.0.0) (2017-10-13)
I feel that current library public API is complete, and should be stable for long time. I feel that current library public API is complete, and should be stable for long time.
Most changes was made to improve performance or/and make library usage easier. Most changes was made to improve performance or/and make library usage easier.

View File

@@ -27,16 +27,18 @@ All cross-platform requirements are enforced at compile time, so serialized data
## Why to use bitsery ## Why to use bitsery
Look at the numbers and features list, and decide yourself. *(benchmarked on Ubuntu with GCC 7.1)* Look at the numbers and features list, and decide yourself.
| | serialize | deserialize | data size | executable size | | | binary size | data size | serialize | deserialize |
|-----------------------------------------------------------|-----------|-------------|-------------|-----------------| |------------------------------|-------------|-----------|-------------|-------------|
| flatbuffers | 1852 ms. | 777 ms. | 27252 bytes | 74544 bytes | | **test_bitsery** | 64704 | **7565** | **1229 ms** | **1086 ms** |
| cereal | 1069 ms. | 1385 ms. | 20208 bytes | 72336 bytes | | **test_bitsery_compression** | 44000 | **4784** | **1370 ms** | **2463 ms** |
| bitsery | 808 ms. | 737 ms. | 14803 bytes | 69784 bytes | | test_yas | 63864 | 11311 | 1616 ms | 1712 ms |
| bitsery fixed-size buffer | 297 ms. | 738 ms. | 14803 bytes | 69928 bytes | | test_yas_compression | 72688 | 8523 | 2387 ms | 2890 ms |
| bitsery optimized serialization flow | 686 ms. | 997 ms. | 6601 bytes | 69320 bytes | | test_cereal | 74848 | 11261 | 6708 ms | 6799 ms |
| bitsery optimized serialization flow + fixed-size buffer | 446 ms. | 996 ms. | 6601 bytes | 69464 bytes | | test_flatbuffers | 67032 | 16100 | 8793 ms | 3028 ms |
*benchmarked on Ubuntu with GCC 7.1.0, more details can be found [here](https://github.com/fraillt/cpp_serializers_benchmark.git)*
If still not convinced read more in library [motivation](doc/design/README.md) section. If still not convinced read more in library [motivation](doc/design/README.md) section.

59
examples/file_stream.cpp Normal file
View File

@@ -0,0 +1,59 @@
#include <bitsery/bitsery.h>
//in order to work with streams include stream adapter
#include <bitsery/adapter/stream.h>
#include <fstream>
#include <iostream>
enum class MyEnum:uint16_t { V1,V2,V3 };
struct MyStruct {
uint32_t i;
MyEnum e;
double f;
};
//define how object should be serialized/deserialized
template <typename S>
void serialize(S& s, MyStruct& o) {
s.value4b(o.i);
s.value2b(o.e);
s.value8b(o.f);
};
using namespace bitsery;
//some helper types
using Stream = std::fstream;
using IOAdapter = IOStreamAdapter;
int main() {
//set some random data
MyStruct data{8941, MyEnum::V2, 0.045};
MyStruct res{};
//open file stream for writing and reading
auto fileName = "test_file.bin";
Stream s{fileName, s.binary | s.trunc | s.out};
if (!s.is_open()) {
std::cout << "cannot open " << fileName << " for writing\n";
return 0;
}
//use same quick serialization function
//streams do not return written size
quickSerialization<IOAdapter>(s, data);
s.close();
//reopen for reading
s.open(fileName, s.binary | s.in);
if (!s.is_open()) {
std::cout << "cannot open " << fileName << " for reading\n";
return 0;
}
//same as serialization, but returns deserialization state as a pair
//first = error code, second = is buffer was successfully read from begin to the end.
auto state = quickDeserialization<IOAdapter>(s, res);
assert(state.first == ReaderError::NoError && state.second);
assert(data.f == res.f && data.i == res.i && data.e == res.e);
}

View File

@@ -0,0 +1,45 @@
#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

@@ -0,0 +1,47 @@
#include <bitsery/bitsery.h>
#include <bitsery/adapter/buffer.h>
//include flexible header, to use flexible syntax
#include <bitsery/flexible.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/...>
//otherwise we'll get static assert error, saying to define serialize function.
#include <bitsery/flexible/vector.h>
enum class MyEnum:uint16_t { V1,V2,V3 };
struct MyStruct {
uint32_t i;
MyEnum e;
std::vector<float> fs;
//define serialize function as usual
template <typename S>
void serialize(S& s) {
//now we can use flexible syntax with
s.archive(i, e, fs);
};
};
using namespace bitsery;
//some helper types
using Buffer = std::vector<uint8_t>;
using OutputAdapter = OutputBufferAdapter<Buffer>;
using InputAdapter = InputBufferAdapter<Buffer>;
int main() {
//set some random data
MyStruct data{8941, MyEnum::V2, {15.0f, -8.5f, 0.045f}};
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.fs == res.fs && data.i == res.i && data.e == res.e);
}

View File

@@ -41,11 +41,12 @@ namespace bitsery {
:_ios{istream} {} :_ios{istream} {}
void read(TValue* data, size_t size) { void read(TValue* data, size_t size) {
_ios.rdbuf()->sgetn( data , size ); if (static_cast<size_t>(_ios.rdbuf()->sgetn( data , size )) != size)
*data = {};
} }
ReaderError error() const { ReaderError error() const {
if (!_ios.bad()) if (_ios.good())
return ReaderError::NoError; return ReaderError::NoError;
return _ios.eof() return _ios.eof()
? ReaderError::DataOverflow ? ReaderError::DataOverflow

View File

@@ -56,9 +56,10 @@ namespace bitsery {
AdapterReader &operator=(const AdapterReader &) = delete; AdapterReader &operator=(const AdapterReader &) = delete;
AdapterReader(AdapterReader &&) noexcept = default; //todo add conditional noexcept
AdapterReader(AdapterReader &&) = default;
AdapterReader &operator=(AdapterReader &&) noexcept = default; AdapterReader &operator=(AdapterReader &&) = default;
~AdapterReader() noexcept = default; ~AdapterReader() noexcept = default;

View File

@@ -117,9 +117,10 @@ namespace bitsery {
AdapterWriter &operator=(const AdapterWriter &) = delete; AdapterWriter &operator=(const AdapterWriter &) = delete;
AdapterWriter(AdapterWriter &&) noexcept = default; //todo add conditional noexcept
AdapterWriter(AdapterWriter &&) = default;
AdapterWriter &operator=(AdapterWriter &&) noexcept = default; AdapterWriter &operator=(AdapterWriter &&) = default;
~AdapterWriter() { ~AdapterWriter() {
flush(); flush();

View File

@@ -113,9 +113,34 @@ namespace bitsery {
size_t maxSize; size_t maxSize;
}; };
//if container, then call procesContainer, this memcpy for fundamental types contiguous container
template<typename S, typename T>
void processMaxSize(S &s, T& data, size_t maxSize, std::true_type) {
processContainer(s, data, maxSize);
};
//overload for const T&
template<typename S, typename T>
void processMaxSize(S &s, const T& data, size_t maxSize, std::true_type) {
processContainer(s, const_cast<T&>(data), maxSize);
};
//try to call serialize overload with maxsize, extensions use this technique
template<typename S, typename T>
void processMaxSize(S &s, T& data, size_t maxSize, std::false_type) {
serialize(s, data, maxSize);
};
//overload for const T&
template<typename S, typename T>
void processMaxSize(S &s, const T& data, size_t maxSize, std::false_type) {
serialize(s, const_cast<T&>(data), maxSize);
};
template<typename S, typename T> template<typename S, typename T>
void serialize(S &s, const MaxSize<T> &ms) { void serialize(S &s, const MaxSize<T> &ms) {
processContainer(s, ms.data, ms.maxSize); processMaxSize(s, ms.data, ms.maxSize, details::IsContainerTraitsDefined<typename std::decay<T>::type>{});
}; };
} }

View File

@@ -69,7 +69,6 @@ namespace bitsery {
return {obj, max}; return {obj, max};
} }
//define serialize function for fundamental types //define serialize function for fundamental types
template<typename S> template<typename S>
void serialize(S &s, bool &v) { void serialize(S &s, bool &v) {

View File

@@ -29,10 +29,10 @@
namespace bitsery { namespace bitsery {
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::map<TArgs ... > &obj) { void serialize(S &s, std::map<TArgs ... > &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
using TKey = typename std::map<TArgs...>::key_type; using TKey = typename std::map<TArgs...>::key_type;
using TValue = typename std::map<TArgs...>::mapped_type; using TValue = typename std::map<TArgs...>::mapped_type;
s.ext(obj, ext::StdMap{std::numeric_limits<size_t>::max()}, s.ext(obj, ext::StdMap{maxSize},
[&s](TKey& key, TValue& value) { [&s](TKey& key, TValue& value) {
s.object(key); s.object(key);
s.object(value); s.object(value);
@@ -40,10 +40,10 @@ namespace bitsery {
} }
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::multimap<TArgs ... > &obj) { void serialize(S &s, std::multimap<TArgs ... > &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
using TKey = typename std::multimap<TArgs...>::key_type; using TKey = typename std::multimap<TArgs...>::key_type;
using TValue = typename std::multimap<TArgs...>::mapped_type; using TValue = typename std::multimap<TArgs...>::mapped_type;
s.ext(obj, ext::StdMap{std::numeric_limits<size_t>::max()}, s.ext(obj, ext::StdMap{maxSize},
[&s](TKey& key, TValue& value) { [&s](TKey& key, TValue& value) {
s.object(key); s.object(key);
s.object(value); s.object(value);

View File

@@ -28,13 +28,13 @@
namespace bitsery { namespace bitsery {
template<typename S, typename T, typename C> template<typename S, typename T, typename C>
void serialize(S &s, std::queue<T, C> &obj) { void serialize(S &s, std::queue<T, C> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdQueue{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdQueue{maxSize});
} }
template<typename S, typename T, typename C, typename Comp> template<typename S, typename T, typename C, typename Comp>
void serialize(S &s, std::priority_queue<T, C, Comp> &obj) { void serialize(S &s, std::priority_queue<T, C, Comp> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdQueue{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdQueue{maxSize});
} }
} }

View File

@@ -29,13 +29,13 @@
namespace bitsery { namespace bitsery {
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::set<TArgs...> &obj) { void serialize(S &s, std::set<TArgs...> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdSet{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdSet{maxSize});
} }
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::multiset<TArgs...> &obj) { void serialize(S &s, std::multiset<TArgs...> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdSet{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdSet{maxSize});
} }
} }

View File

@@ -28,8 +28,8 @@
namespace bitsery { namespace bitsery {
template<typename S, typename T, typename C> template<typename S, typename T, typename C>
void serialize(S &s, std::stack<T, C> &obj) { void serialize(S &s, std::stack<T, C> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdStack{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdStack{maxSize});
} }
} }

View File

@@ -29,10 +29,10 @@
namespace bitsery { namespace bitsery {
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::unordered_map<TArgs ... > &obj) { void serialize(S &s, std::unordered_map<TArgs ... > &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
using TKey = typename std::unordered_map<TArgs...>::key_type; using TKey = typename std::unordered_map<TArgs...>::key_type;
using TValue = typename std::unordered_map<TArgs...>::mapped_type; using TValue = typename std::unordered_map<TArgs...>::mapped_type;
s.ext(obj, ext::StdMap{std::numeric_limits<size_t>::max()}, s.ext(obj, ext::StdMap{maxSize},
[&s](TKey& key, TValue& value) { [&s](TKey& key, TValue& value) {
s.object(key); s.object(key);
s.object(value); s.object(value);
@@ -40,10 +40,10 @@ namespace bitsery {
} }
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::unordered_multimap<TArgs ... > &obj) { void serialize(S &s, std::unordered_multimap<TArgs ... > &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
using TKey = typename std::unordered_multimap<TArgs...>::key_type; using TKey = typename std::unordered_multimap<TArgs...>::key_type;
using TValue = typename std::unordered_multimap<TArgs...>::mapped_type; using TValue = typename std::unordered_multimap<TArgs...>::mapped_type;
s.ext(obj, ext::StdMap{std::numeric_limits<size_t>::max()}, s.ext(obj, ext::StdMap{maxSize},
[&s](TKey& key, TValue& value) { [&s](TKey& key, TValue& value) {
s.object(key); s.object(key);
s.object(value); s.object(value);

View File

@@ -29,13 +29,13 @@
namespace bitsery { namespace bitsery {
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::unordered_set<TArgs...> &obj) { void serialize(S &s, std::unordered_set<TArgs...> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdSet{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdSet{maxSize});
} }
template<typename S, typename ... TArgs> template<typename S, typename ... TArgs>
void serialize(S &s, std::unordered_multiset<TArgs...> &obj) { void serialize(S &s, std::unordered_multiset<TArgs...> &obj, size_t maxSize = std::numeric_limits<size_t>::max()) {
s.ext(obj, ext::StdSet{std::numeric_limits<size_t>::max()}); s.ext(obj, ext::StdSet{maxSize});
} }
} }

109
tests/adapter_stream.cpp Normal file
View File

@@ -0,0 +1,109 @@
//MIT License
//
//Copyright (c) 2017 Mindaugas Vinkelis
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
#include <gmock/gmock.h>
#include <bitsery/adapter/stream.h>
#include <bitsery/adapter_writer.h>
#include <bitsery/adapter_reader.h>
#include <sstream>
//some helper types
using Stream = std::stringstream;
using OutputAdapter = bitsery::OutputStreamAdapter;
using InputAdapter = bitsery::InputStreamAdapter ;
using Writer = bitsery::AdapterWriter<bitsery::OutputStreamAdapter, bitsery::DefaultConfig>;
using Reader = bitsery::AdapterReader<bitsery::InputStreamAdapter, bitsery::DefaultConfig>;
using testing::Eq;
TEST(AdapterIOStream, WrittenBytesCountReturns0) {
//setup data
uint8_t t1 = 111;
Stream buf{};
Writer w{{buf}};
w.writeBytes<1>(t1);
w.flush();
EXPECT_THAT(buf.str().size(), Eq(1));
EXPECT_THAT(w.writtenBytesCount(), Eq(0));
}
TEST(AdapterIOStream, CorrectlyReturnsIsCompletedSuccessfully) {
//setup data
uint8_t t1 = 111;
Stream buf{};
Writer w{{buf}};
w.writeBytes<1>(t1);
w.flush();
Reader r{{buf}};
uint8_t r1{};
EXPECT_THAT(r.isCompletedSuccessfully(), Eq(false));
r.readBytes<1>(r1);
EXPECT_THAT(r.isCompletedSuccessfully(), Eq(true));
EXPECT_THAT(r1, Eq(t1));
}
TEST(AdapterIOStream, ReadingMoreThanAvailableReturnsZero) {
//setup data
uint8_t t1 = 111;
Stream buf{};
Writer w{{buf}};
w.writeBytes<1>(t1);
w.flush();
Reader r{{buf}};
uint8_t r1{};
r.readBytes<1>(r1);
r.readBytes<1>(r1);
EXPECT_THAT(r1, Eq(0));
}
//this is strange, but probably stringstream doesnt use any of the base methods that sets io_base::iostate flags
TEST(AdapterIOStream, WhenReadingStringStreamThenErrorCodeAlwaysReturnsNoError) {
//setup data
uint8_t t1 = 111;
Stream buf{};
Writer w{{buf}};
w.writeBytes<1>(t1);
w.flush();
Reader r{{buf}};
uint8_t r1{};
EXPECT_THAT(r.isCompletedSuccessfully(), Eq(false));
EXPECT_THAT(r.error(), Eq(bitsery::ReaderError::NoError));
r.readBytes<1>(r1);
EXPECT_THAT(r.isCompletedSuccessfully(), Eq(true));
EXPECT_THAT(r.error(), Eq(bitsery::ReaderError::NoError));
EXPECT_THAT(r1, Eq(t1));
r.readBytes<1>(r1);
EXPECT_THAT(r1, Eq(0));
//should by overflow error, but it all iostate flags are set to false...
EXPECT_THAT(r.error(), Eq(bitsery::ReaderError::NoError));
}

View File

@@ -141,6 +141,15 @@ T procArchive(const T& testData) {
return res; return res;
} }
template <typename T>
T procArchiveWithMaxSize(const T& testData) {
SerializationContext ctx;
ctx.createSerializer().archive(bitsery::maxSize(testData, 100));
T res;
ctx.createDeserializer().archive(bitsery::maxSize(res, 100));
return res;
}
TEST(FlexibleSyntax, CStyleArrayForValueTypesAsContainer) { TEST(FlexibleSyntax, CStyleArrayForValueTypesAsContainer) {
const int t1[3]{8748,-484,45}; const int t1[3]{8748,-484,45};
int r1[3]{0,0,0}; int r1[3]{0,0,0};
@@ -181,6 +190,8 @@ TEST(FlexibleSyntax, StdString) {
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2)); EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
} }
TEST(FlexibleSyntax, StdArray) { TEST(FlexibleSyntax, StdArray) {
@@ -189,6 +200,7 @@ TEST(FlexibleSyntax, StdArray) {
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2)); EXPECT_THAT(procArchive(t2), Eq(t2));
} }
TEST(FlexibleSyntax, StdVector) { TEST(FlexibleSyntax, StdVector) {
@@ -197,6 +209,9 @@ TEST(FlexibleSyntax, StdVector) {
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2)); EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
} }
TEST(FlexibleSyntax, StdList) { TEST(FlexibleSyntax, StdList) {
@@ -205,6 +220,9 @@ TEST(FlexibleSyntax, StdList) {
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2)); EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
} }
TEST(FlexibleSyntax, StdForwardList) { TEST(FlexibleSyntax, StdForwardList) {
@@ -213,6 +231,9 @@ TEST(FlexibleSyntax, StdForwardList) {
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2)); EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
} }
TEST(FlexibleSyntax, StdDeque) { TEST(FlexibleSyntax, StdDeque) {
@@ -221,6 +242,9 @@ TEST(FlexibleSyntax, StdDeque) {
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchive(t2), Eq(t2)); EXPECT_THAT(procArchive(t2), Eq(t2));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t2), Eq(t2));
} }
TEST(FlexibleSyntax, StdQueue) { TEST(FlexibleSyntax, StdQueue) {
@@ -229,6 +253,8 @@ TEST(FlexibleSyntax, StdQueue) {
t1.push("second string"); t1.push("second string");
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
} }
TEST(FlexibleSyntax, StdPriorityQueue) { TEST(FlexibleSyntax, StdPriorityQueue) {
@@ -255,6 +281,8 @@ TEST(FlexibleSyntax, StdStack) {
t1.push("second string"); t1.push("second string");
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
} }
TEST(FlexibleSyntax, StdUnorderedMap) { TEST(FlexibleSyntax, StdUnorderedMap) {
@@ -263,6 +291,7 @@ TEST(FlexibleSyntax, StdUnorderedMap) {
t1.emplace(-5484,-845); t1.emplace(-5484,-845);
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
} }
TEST(FlexibleSyntax, StdUnorderedMultiMap) { TEST(FlexibleSyntax, StdUnorderedMultiMap) {
@@ -272,6 +301,7 @@ TEST(FlexibleSyntax, StdUnorderedMultiMap) {
t1.emplace("one",897); t1.emplace("one",897);
EXPECT_TRUE(procArchive(t1) == t1); EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
} }
TEST(FlexibleSyntax, StdMap) { TEST(FlexibleSyntax, StdMap) {
@@ -280,6 +310,7 @@ TEST(FlexibleSyntax, StdMap) {
t1.emplace(-5484,-845); t1.emplace(-5484,-845);
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
} }
TEST(FlexibleSyntax, StdMultiMap) { TEST(FlexibleSyntax, StdMultiMap) {
@@ -308,6 +339,7 @@ TEST(FlexibleSyntax, StdUnorderedSet) {
t1.emplace("three"); t1.emplace("three");
EXPECT_TRUE(procArchive(t1) == t1); EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
} }
TEST(FlexibleSyntax, StdUnorderedMultiSet) { TEST(FlexibleSyntax, StdUnorderedMultiSet) {
@@ -318,6 +350,7 @@ TEST(FlexibleSyntax, StdUnorderedMultiSet) {
t1.emplace("one"); t1.emplace("one");
EXPECT_TRUE(procArchive(t1) == t1); EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
} }
TEST(FlexibleSyntax, StdSet) { TEST(FlexibleSyntax, StdSet) {
@@ -327,7 +360,7 @@ TEST(FlexibleSyntax, StdSet) {
t1.emplace("three"); t1.emplace("three");
EXPECT_TRUE(procArchive(t1) == t1); EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
} }
TEST(FlexibleSyntax, StdMultiSet) { TEST(FlexibleSyntax, StdMultiSet) {
@@ -339,6 +372,7 @@ TEST(FlexibleSyntax, StdMultiSet) {
t1.emplace("two"); t1.emplace("two");
EXPECT_TRUE(procArchive(t1) == t1); EXPECT_TRUE(procArchive(t1) == t1);
EXPECT_TRUE(procArchiveWithMaxSize(t1) == t1);
} }
@@ -348,4 +382,5 @@ TEST(FlexibleSyntax, NestedTypes) {
t1.emplace("other key", std::vector<std::string>{"just a string"}); t1.emplace("other key", std::vector<std::string>{"just a string"});
EXPECT_THAT(procArchive(t1), Eq(t1)); EXPECT_THAT(procArchive(t1), Eq(t1));
EXPECT_THAT(procArchiveWithMaxSize(t1), Eq(t1));
} }