mirror of
https://github.com/fraillt/bitsery.git
synced 2026-08-16 08:09:48 +00:00
range implementation complete
This commit is contained in:
110
include/Common.h
110
include/Common.h
@@ -51,8 +51,25 @@ struct BIGGER_TYPE<char> {
|
||||
template <typename T>
|
||||
constexpr size_t ARITHMETIC_OR_ENUM_SIZE = std::is_arithmetic<T>::value || std::is_enum<T>::value ? sizeof(T) : 0;
|
||||
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct SAME_SIZE_UNSIGNED_TYPE {
|
||||
typedef std::make_unsigned_t<T> type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SAME_SIZE_UNSIGNED_TYPE<T, typename std::enable_if<std::is_enum<T>::value>::type> {
|
||||
typedef std::make_unsigned_t<std::underlying_type_t<T>> type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SAME_SIZE_UNSIGNED_TYPE<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
|
||||
typedef std::conditional_t<std::is_same<T,float>::value, uint32_t, uint64_t> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using UINT_FOR_FLOATING_POINT = std::conditional_t<std::is_same<T,float>::value, uint32_t, uint64_t>;
|
||||
using SAME_SIZE_UNSIGNED = typename SAME_SIZE_UNSIGNED_TYPE<T>::type;
|
||||
|
||||
|
||||
template <size_t SIZE>
|
||||
struct ProcessAnyType {
|
||||
@@ -84,78 +101,65 @@ constexpr size_t calcRequiredBits(T min, T max) {
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class Enable = void>
|
||||
class RangeSpec {
|
||||
public:
|
||||
template <typename T, typename Enable = void>
|
||||
struct RangeSpec {
|
||||
|
||||
constexpr RangeSpec(T min, T max)
|
||||
:_min{min},
|
||||
_max{max},
|
||||
_bitsRequired{calcRequiredBits(_min, _max)}
|
||||
{
|
||||
constexpr RangeSpec(T minValue, T maxValue)
|
||||
:min{minValue},
|
||||
max{maxValue},
|
||||
bitsRequired{calcRequiredBits(min, max)}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr size_t bitsRequired() const {
|
||||
return _bitsRequired;
|
||||
}
|
||||
|
||||
private:
|
||||
const T _min;
|
||||
const T _max;
|
||||
const size_t _bitsRequired;
|
||||
const T min;
|
||||
const T max;
|
||||
const size_t bitsRequired;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class RangeSpec<T, typename std::enable_if<std::is_enum<T>::value>::type> {
|
||||
public:
|
||||
|
||||
constexpr RangeSpec(T min, T max):
|
||||
_min{min},
|
||||
_max{max},
|
||||
_bitsRequired{calcRequiredBits(
|
||||
static_cast<std::underlying_type_t<T>>(_min),
|
||||
static_cast<std::underlying_type_t<T>>(_max))}
|
||||
struct RangeSpec<T, typename std::enable_if<std::is_enum<T>::value>::type> {
|
||||
|
||||
constexpr RangeSpec(T minValue, T maxValue):
|
||||
min{minValue},
|
||||
max{maxValue},
|
||||
bitsRequired{calcRequiredBits(
|
||||
static_cast<std::underlying_type_t<T>>(min),
|
||||
static_cast<std::underlying_type_t<T>>(max))}
|
||||
{
|
||||
}
|
||||
constexpr size_t bitsRequired() const {
|
||||
return _bitsRequired;
|
||||
}
|
||||
const T min;
|
||||
const T max;
|
||||
const size_t bitsRequired;
|
||||
};
|
||||
|
||||
private:
|
||||
const T _min;
|
||||
const T _max;
|
||||
const size_t _bitsRequired;
|
||||
//this class is used to make default RangeSpec float specialization always prefer constructor with precision
|
||||
struct BitsConstraint {
|
||||
explicit constexpr BitsConstraint(size_t bits):value{bits} {}
|
||||
const size_t value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class RangeSpec<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
|
||||
public:
|
||||
|
||||
//todo bits should be separate size not implicitly convertable from floating point types, so these constructors would be ambiguous
|
||||
constexpr RangeSpec(T min, T max, size_t bits, int tmp):
|
||||
_min{min},
|
||||
_max{max},
|
||||
_bitsRequired{bits}
|
||||
struct RangeSpec<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
|
||||
|
||||
constexpr RangeSpec(T minValue, T maxValue, BitsConstraint bits):
|
||||
min{minValue},
|
||||
max{maxValue},
|
||||
bitsRequired{bits.value}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr RangeSpec(T min, T max, T precision):
|
||||
_min{min},
|
||||
_max{max},
|
||||
_bitsRequired{calcRequiredBits<UINT_FOR_FLOATING_POINT<T>>({}, ((max - min) / precision))}
|
||||
constexpr RangeSpec(T minValue, T maxValue, T precision):
|
||||
min{minValue},
|
||||
max{maxValue},
|
||||
bitsRequired{calcRequiredBits<SAME_SIZE_UNSIGNED<T>>({}, ((max - min) / precision))}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
constexpr size_t bitsRequired() const {
|
||||
return _bitsRequired;
|
||||
}
|
||||
|
||||
private:
|
||||
const T _min;
|
||||
const T _max;
|
||||
const size_t _bitsRequired;
|
||||
const T min;
|
||||
const T max;
|
||||
const size_t bitsRequired;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
static_assert(std::numeric_limits<double>::is_iec559, "");
|
||||
|
||||
constexpr size_t ValueSize = VSIZE == 0 ? sizeof(T) : VSIZE;
|
||||
_reader.template readBytes<ValueSize>(reinterpret_cast<UINT_FOR_FLOATING_POINT<T>&>(v));
|
||||
_reader.template readBytes<ValueSize>(reinterpret_cast<SAME_SIZE_UNSIGNED<T>&>(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ public:
|
||||
|
||||
template <typename T>
|
||||
Deserializer& range(T& v, const RangeSpec<T>& range) {
|
||||
//ValueWriteProxy<T> proxy{v, range};
|
||||
//_reader.template readBits(proxy.value(), r.bitsRequired());
|
||||
_reader.template readBits(reinterpret_cast<SAME_SIZE_UNSIGNED<T>&>(v), range.bitsRequired);
|
||||
setRangeValue(v, range);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -186,5 +186,28 @@ private:
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* functions for range
|
||||
*/
|
||||
template<typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
|
||||
void setRangeValue(T& v, const RangeSpec<T>& r) {
|
||||
v += r.min;
|
||||
};
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
|
||||
void setRangeValue(T& v, const RangeSpec<T>& r) {
|
||||
using VT = std::underlying_type_t<T>;
|
||||
reinterpret_cast<VT&>(v) += static_cast<VT>(r.min);
|
||||
};
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
|
||||
void setRangeValue(T& v, const RangeSpec<T>& r) {
|
||||
using UIT = SAME_SIZE_UNSIGNED<T>;
|
||||
const auto intRep = reinterpret_cast<UIT&>(v);
|
||||
const UIT maxUint = (static_cast<UIT>(1) << r.bitsRequired) - 1;
|
||||
v = r.min + (static_cast<T>(intRep) / maxUint) * (r.max - r.min);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TMP_DESERIALIZER_H
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
static_assert(std::numeric_limits<double>::is_iec559, "");
|
||||
|
||||
constexpr size_t ValueSize = VSIZE == 0 ? sizeof(T) : VSIZE;
|
||||
_writter.template writeBytes<ValueSize>(reinterpret_cast<const UINT_FOR_FLOATING_POINT<T>&>(v));
|
||||
_writter.template writeBytes<ValueSize>(reinterpret_cast<const SAME_SIZE_UNSIGNED<T>&>(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ public:
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
Serializer& range(const T& v, const RangeSpec<T>& r) {
|
||||
//assert(r.isValid(v));
|
||||
//_writter.template writeBits(r.value(v), r.bitsRequired());
|
||||
Serializer& range(const T& v, const RangeSpec<T>& range) {
|
||||
assert(isRangeValid(v, range));
|
||||
_writter.template writeBits(getRangeValue(v,range), range.bitsRequired);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,41 @@ private:
|
||||
if (size)
|
||||
_writter.template writeBuffer<VSIZE>(str, size);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* functions for range
|
||||
*/
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
|
||||
bool isRangeValid(const T& v, const RangeSpec<T>& r) {
|
||||
return !(r.min > v || v > r.max);
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
|
||||
bool isRangeValid(const T& v, const RangeSpec<T>& r) {
|
||||
using VT = std::underlying_type_t<T>;
|
||||
return !(static_cast<VT>(r.min) > static_cast<VT>(v)
|
||||
|| static_cast<VT>(v) > static_cast<VT>(r.max));
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
|
||||
auto getRangeValue(const T& v, const RangeSpec<T>& r) {
|
||||
return static_cast<SAME_SIZE_UNSIGNED<T>>(v - r.min);
|
||||
};
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
|
||||
auto getRangeValue(const T& v, const RangeSpec<T>& r) {
|
||||
return static_cast<SAME_SIZE_UNSIGNED<T>>(v) - static_cast<SAME_SIZE_UNSIGNED<T>>(r.min);
|
||||
};
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
|
||||
auto getRangeValue(const T& v, const RangeSpec<T>& r) {
|
||||
using VT = SAME_SIZE_UNSIGNED<T>;
|
||||
const VT maxUint = (static_cast<VT>(1) << r.bitsRequired) - 1;
|
||||
const auto ratio = (v - r.min) / (r.max - r.min);
|
||||
return static_cast<VT>(ratio * maxUint);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -15,29 +15,34 @@ include_directories(SYSTEM ${GTEST_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
file(GLOB TEST_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
add_executable(${TEST_PROJECT_NAME} ${TEST_SRC_FILES})
|
||||
add_dependencies(${TEST_PROJECT_NAME} googletest)
|
||||
|
||||
set_property(TARGET ${TEST_PROJECT_NAME} PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET ${TEST_PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
FOREACH(TEST_PROJECT_FILE ${TEST_SRC_FILES})
|
||||
get_filename_component(TEST_PROJECT_NAME ${TEST_PROJECT_FILE} NAME_WE)
|
||||
|
||||
add_executable(${TEST_PROJECT_NAME} ${TEST_SRC_FILES})
|
||||
add_dependencies(${TEST_PROJECT_NAME} googletest)
|
||||
|
||||
set_property(TARGET ${TEST_PROJECT_NAME} PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET ${TEST_PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
||||
if(NOT WIN32 OR MINGW)
|
||||
FOREACH(LIBNAME ${GTEST_LINK_LIBNAMES})
|
||||
target_link_libraries(${TEST_PROJECT_NAME} ${GTEST_LIBS_DIR}/lib${LIBNAME}.a )
|
||||
ENDFOREACH()
|
||||
else()
|
||||
FOREACH(LIBNAME ${GTEST_LINK_LIBNAMES})
|
||||
target_link_libraries(${TEST_PROJECT_NAME}
|
||||
debug ${GTEST_LIBS_DIR}/DebugLibs/${CMAKE_FIND_LIBRARY_PREFIXES}${LIBNAME}${CMAKE_FIND_LIBRARY_SUFFIXES}
|
||||
optimized ${GTEST_LIBS_DIR}/ReleaseLibs/${CMAKE_FIND_LIBRARY_PREFIXES}${LIBNAME}${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
ENDFOREACH()
|
||||
endif()
|
||||
if(NOT WIN32 OR MINGW)
|
||||
FOREACH(LIBNAME ${GTEST_LINK_LIBNAMES})
|
||||
target_link_libraries(${TEST_PROJECT_NAME} ${GTEST_LIBS_DIR}/lib${LIBNAME}.a )
|
||||
ENDFOREACH()
|
||||
else()
|
||||
FOREACH(LIBNAME ${GTEST_LINK_LIBNAMES})
|
||||
target_link_libraries(${TEST_PROJECT_NAME}
|
||||
debug ${GTEST_LIBS_DIR}/DebugLibs/${CMAKE_FIND_LIBRARY_PREFIXES}${LIBNAME}${CMAKE_FIND_LIBRARY_SUFFIXES}
|
||||
optimized ${GTEST_LIBS_DIR}/ReleaseLibs/${CMAKE_FIND_LIBRARY_PREFIXES}${LIBNAME}${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
ENDFOREACH()
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TEST_PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
add_test(NAME all_tests COMMAND $<TARGET_FILE:${TEST_PROJECT_NAME}>)
|
||||
target_link_libraries(${TEST_PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
add_test(NAME ${TEST_PROJECT_NAME} COMMAND $<TARGET_FILE:${TEST_PROJECT_NAME}>)
|
||||
|
||||
ENDFOREACH()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,17 +6,128 @@
|
||||
#include "SerializationTestUtils.h"
|
||||
using namespace testing;
|
||||
|
||||
TEST(Ranges, RequiredBitsIsConstexpr) {
|
||||
TEST(SerializeRange, RequiredBitsIsConstexpr) {
|
||||
constexpr RangeSpec<int> r1{0, 31};
|
||||
static_assert(r1.bitsRequired() == 5);
|
||||
static_assert(r1.bitsRequired == 5);
|
||||
|
||||
constexpr RangeSpec<MyEnumClass> r2{MyEnumClass::E1, MyEnumClass::E4};
|
||||
static_assert(r2.bitsRequired() == 2);
|
||||
static_assert(r2.bitsRequired == 2);
|
||||
|
||||
constexpr RangeSpec<double> r3{-1.0,1.0, 5u, 0};
|
||||
static_assert(r3.bitsRequired() == 5);
|
||||
constexpr RangeSpec<double> r3{-1.0,1.0, BitsConstraint{5u}};
|
||||
//EXPECT_THAT(r1.bitsRequired, Eq(5));
|
||||
static_assert(r3.bitsRequired == 5);
|
||||
|
||||
constexpr RangeSpec<float> r4{-1.0f,1.0f, 0.01f};
|
||||
static_assert(r4.bitsRequired() == 8);
|
||||
static_assert(r4.bitsRequired == 8);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SerializeRange, IntegerNegative) {
|
||||
SerializationContext ctx;
|
||||
constexpr RangeSpec<int> r1{-50, 50};
|
||||
int t1{-8};
|
||||
int res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
EXPECT_THAT(res1, Eq(t1));
|
||||
|
||||
}
|
||||
|
||||
TEST(SerializeRange, IntegerPositive) {
|
||||
SerializationContext ctx;
|
||||
constexpr RangeSpec<unsigned> r1{4, 10};
|
||||
unsigned t1{8};
|
||||
unsigned res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
EXPECT_THAT(res1, Eq(t1));
|
||||
|
||||
}
|
||||
|
||||
TEST(SerializeRange, EnumTypes) {
|
||||
SerializationContext ctx;
|
||||
constexpr RangeSpec<MyEnumClass> r1{MyEnumClass::E2, MyEnumClass::E4};
|
||||
MyEnumClass t1{MyEnumClass::E2};
|
||||
MyEnumClass res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
EXPECT_THAT(res1, Eq(t1));
|
||||
|
||||
}
|
||||
|
||||
TEST(SerializeRange, FloatUsingPrecisionConstraint1) {
|
||||
SerializationContext ctx;
|
||||
constexpr float precision{0.01f};
|
||||
constexpr float min{-1.0f};
|
||||
constexpr float max{1.0f};
|
||||
float t1{0.5f};
|
||||
constexpr RangeSpec<float> r1{min, max, precision};
|
||||
|
||||
float res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
EXPECT_THAT(res1, ::testing::FloatNear(t1, (max - min) * precision));
|
||||
}
|
||||
|
||||
TEST(SerializeRange, DoubleUsingPrecisionConstraint2) {
|
||||
SerializationContext ctx;
|
||||
constexpr double precision{0.000002};
|
||||
constexpr double min{50.0};
|
||||
constexpr double max{100000.0};
|
||||
double t1{38741.0};
|
||||
constexpr RangeSpec<double> r1{min, max, precision};
|
||||
|
||||
double res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(5));
|
||||
EXPECT_THAT(res1, ::testing::DoubleNear(t1, (max - min) * precision));
|
||||
}
|
||||
|
||||
TEST(SerializeRange, FloatUsingBitsSizeConstraint1) {
|
||||
SerializationContext ctx;
|
||||
constexpr size_t bits = 8;
|
||||
constexpr float min{-1.0f};
|
||||
constexpr float max{1.0f};
|
||||
float t1{0.5f};
|
||||
constexpr RangeSpec<float> r1{min, max, BitsConstraint(bits)};
|
||||
|
||||
float res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(1));
|
||||
EXPECT_THAT(res1, ::testing::FloatNear(t1, (max - min) / (static_cast<SAME_SIZE_UNSIGNED<float>>(1) << bits)));
|
||||
}
|
||||
|
||||
TEST(SerializeRange, DoubleUsingBitsSizeConstraint2) {
|
||||
SerializationContext ctx;
|
||||
constexpr size_t bits = 50;
|
||||
constexpr double min{50.0};
|
||||
constexpr double max{100000.0};
|
||||
double t1{38741};
|
||||
constexpr RangeSpec<double> r1{min, max, BitsConstraint(bits)};
|
||||
|
||||
double res1;
|
||||
|
||||
ctx.createSerializer().range(t1, r1);
|
||||
ctx.createDeserializer().range(res1, r1);
|
||||
|
||||
EXPECT_THAT(ctx.getBufferSize(), Eq(7));
|
||||
EXPECT_THAT(res1, ::testing::DoubleNear(t1, (max - min) / (static_cast<SAME_SIZE_UNSIGNED<double>>(1) << bits)));
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ public:
|
||||
}
|
||||
|
||||
Deserializer<BufferReader> createDeserializer() {
|
||||
bw->flush();
|
||||
br = std::make_unique<BufferReader>(buf);
|
||||
return {*br};
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "SerializationTestUtils.h"
|
||||
using namespace testing;
|
||||
|
||||
TEST(SerializerText, BasicString) {
|
||||
TEST(SerializeText, BasicString) {
|
||||
SerializationContext ctx;
|
||||
std::string t1 = "some random text";
|
||||
std::string res;
|
||||
@@ -19,7 +19,7 @@ TEST(SerializerText, BasicString) {
|
||||
|
||||
}
|
||||
|
||||
TEST(SerializerText, WhenSizeOfTypeNotEqualsOneThenSetSizeExplicitly) {
|
||||
TEST(SerializeText, WhenSizeOfTypeNotEqualsOneThenSetSizeExplicitly) {
|
||||
SerializationContext ctx;
|
||||
constexpr auto VSIZE = sizeof(char32_t);
|
||||
std::basic_string<char32_t> t1 = U"some random text";
|
||||
@@ -32,7 +32,7 @@ TEST(SerializerText, WhenSizeOfTypeNotEqualsOneThenSetSizeExplicitly) {
|
||||
EXPECT_THAT(res, ContainerEq(t1));
|
||||
}
|
||||
|
||||
TEST(SerializerText, BasicStringUseSizeMethodNotNullterminatedLength) {
|
||||
TEST(SerializeText, BasicStringUseSizeMethodNotNullterminatedLength) {
|
||||
SerializationContext ctx;
|
||||
std::wstring t1(L"some random text\0xxxxxx", 20);
|
||||
std::wstring wres;
|
||||
@@ -64,7 +64,7 @@ TEST(SerializerText, BasicStringUseSizeMethodNotNullterminatedLength) {
|
||||
|
||||
const int CARR_LENGTH = 10;
|
||||
|
||||
TEST(SerializerText, CArraySerializesTextLength) {
|
||||
TEST(SerializeText, CArraySerializesTextLength) {
|
||||
SerializationContext ctx;
|
||||
char t1[CARR_LENGTH]{"some text"};
|
||||
char r1[CARR_LENGTH]{};
|
||||
@@ -89,7 +89,7 @@ TEST(SerializerText, CArraySerializesTextLength) {
|
||||
EXPECT_THAT(r1, ContainerEq(t1));
|
||||
}
|
||||
|
||||
TEST(SerializerText, WhenCArrayWithLargerTypeThenSetSizeExplicitly) {
|
||||
TEST(SerializeText, WhenCArrayWithLargerTypeThenSetSizeExplicitly) {
|
||||
SerializationContext ctx;
|
||||
char32_t t1[10]{U"some text"};
|
||||
char32_t r1[10]{};
|
||||
@@ -103,7 +103,7 @@ TEST(SerializerText, WhenCArrayWithLargerTypeThenSetSizeExplicitly) {
|
||||
}
|
||||
|
||||
|
||||
TEST(SerializerText, WhenCArrayNotNullterminatedThenMakeItNullterminated) {
|
||||
TEST(SerializeText, WhenCArrayNotNullterminatedThenMakeItNullterminated) {
|
||||
SerializationContext ctx;
|
||||
char t1[CARR_LENGTH]{"some text"};
|
||||
//make last character not nullterminated
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
//
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <Deserializer.h>
|
||||
#include <BufferReader.h>
|
||||
#include "BufferWriter.h"
|
||||
#include "Serializer.h"
|
||||
#include "SerializationTestUtils.h"
|
||||
|
||||
#include "DeltaSerializer.h"
|
||||
#include "DeltaDeserializer.h"
|
||||
|
||||
#include <list>
|
||||
#include <array>
|
||||
|
||||
using testing::Eq;
|
||||
using testing::StrEq;
|
||||
@@ -64,11 +60,9 @@ SERIALIZE(Y)
|
||||
}
|
||||
|
||||
|
||||
TEST(Serializer, GeneralConceptTest) {
|
||||
TEST(SerializeObject, GeneralConceptTest) {
|
||||
//std::string buf;
|
||||
std::vector<uint8_t> buf{};
|
||||
BufferWriter bw{ buf };
|
||||
Serializer<BufferWriter> ser(bw);
|
||||
SerializationContext ctx;
|
||||
Y y{};
|
||||
y.y = 3423;
|
||||
y.arr[0] = 111;
|
||||
@@ -87,16 +81,17 @@ TEST(Serializer, GeneralConceptTest) {
|
||||
z.x = X{ 234 };
|
||||
|
||||
|
||||
serialize(ser, y);
|
||||
serialize(ser, z);
|
||||
auto ser = ctx.createSerializer();
|
||||
ser.object(y);
|
||||
ser.object(z);
|
||||
|
||||
BufferReader br{ buf };
|
||||
Deserializer<BufferReader> des(br);
|
||||
|
||||
Y yres{};
|
||||
Z zres{};
|
||||
serialize(des, yres);
|
||||
serialize(des, zres);
|
||||
|
||||
auto des = ctx.createDeserializer();
|
||||
des.object(yres);
|
||||
des.object(zres);
|
||||
|
||||
EXPECT_THAT(yres.y, Eq(y.y));
|
||||
EXPECT_THAT(yres.vx, ContainerEq(y.vx));
|
||||
|
||||
@@ -3,36 +3,25 @@
|
||||
//
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <Deserializer.h>
|
||||
#include <BufferReader.h>
|
||||
#include "BufferWriter.h"
|
||||
#include "Serializer.h"
|
||||
|
||||
#include "SerializationTestUtils.h"
|
||||
|
||||
using testing::Eq;
|
||||
|
||||
template <typename T>
|
||||
bool SerializeDeserializeValue(const T& v) {
|
||||
T res{};
|
||||
std::vector<uint8_t> buf{};
|
||||
|
||||
BufferWriter bw{buf};
|
||||
Serializer<BufferWriter> ser(bw);
|
||||
ser.value(v);
|
||||
bw.flush();
|
||||
|
||||
BufferReader br{buf};
|
||||
Deserializer<BufferReader> des(br);
|
||||
des.value(res);
|
||||
SerializationContext ctx;
|
||||
ctx.createSerializer().value(v);
|
||||
ctx.createDeserializer().value(res);
|
||||
return v == res;
|
||||
}
|
||||
|
||||
TEST(SerializerValues, IntegerTypes) {
|
||||
TEST(SerializeValues, IntegerTypes) {
|
||||
EXPECT_THAT(SerializeDeserializeValue(-449874), Eq(true));
|
||||
EXPECT_THAT(SerializeDeserializeValue(34u), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializerValues, EnumTypes) {
|
||||
TEST(SerializeValues, EnumTypes) {
|
||||
enum E1{
|
||||
A1,B1,C1,D1
|
||||
};
|
||||
@@ -47,12 +36,12 @@ TEST(SerializerValues, EnumTypes) {
|
||||
EXPECT_THAT(SerializeDeserializeValue(E3::C3), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializerValues, FloatingPointTypes) {
|
||||
TEST(SerializeValues, FloatingPointTypes) {
|
||||
EXPECT_THAT(SerializeDeserializeValue(-484.465), Eq(true));
|
||||
EXPECT_THAT(SerializeDeserializeValue(0.00000015f), Eq(true));
|
||||
}
|
||||
|
||||
TEST(SerializerValues, ExplicitTypeSize) {
|
||||
TEST(SerializeValues, ExplicitTypeSize) {
|
||||
int v{23472};
|
||||
constexpr size_t TSIZE = sizeof(v);
|
||||
std::vector<uint8_t> buf{};
|
||||
|
||||
Reference in New Issue
Block a user