in progress of range values feature

This commit is contained in:
fraillt
2017-02-15 15:10:38 +02:00
parent 8607338bfb
commit 0ed492d9b4
6 changed files with 132 additions and 1 deletions

View File

@@ -7,5 +7,9 @@ file(GLOB EXAMPLE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
FOREACH(EXAMPLE ${EXAMPLE_FILES})
get_filename_component(EXAMPLE_NAME ${EXAMPLE} NAME_WE)
add_executable(${EXAMPLE_NAME} ${EXAMPLE})
set_property(TARGET ${EXAMPLE_NAME} PROPERTY CXX_STANDARD 14)
set_property(TARGET ${EXAMPLE_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
ENDFOREACH()

View File

@@ -72,6 +72,76 @@ struct ProcessAnyType<0> {
template <typename S, typename T, typename std::enable_if<std::is_same<T, ObjectType>::value || std::is_same<T, const ObjectType>::value>::type* = nullptr> \
S& serialize(S& s, T& o)
extern int no_symbol;
template <typename T>
constexpr size_t calcRequiredBits(T min, T max) {
(T)min != min ? throw (no_symbol) : 0;
assert(min < max);
size_t res{};
for (auto diff = max - min; diff > 0; diff >>= 1)
++res;
return res;
}
template <typename T, class Enable = void>
class RangeSpec {
public:
constexpr RangeSpec(T min, T max)
:_min{min},
_max{max},
_bitsRequired{calcRequiredBits(_min, _max)}
{
}
constexpr size_t bitsRequired() const {
return _bitsRequired;
}
constexpr bool isValid(const T& v) const {
return !(_max < v || v < _min);
}
private:
T _min;
T _max;
size_t _bitsRequired;
};
template <typename T>
class RangeSpec<T, typename std::enable_if<std::is_enum<T>::value>::type> {
public:
using value_type = typename std::underlying_type<T>::type;
constexpr RangeSpec(T min, T max):
_min{static_cast<value_type>(min)},
_max{static_cast<value_type>(max)},
_bitsRequired{calcRequiredBits(_min, _max)}
{
}
constexpr size_t bitsRequired() const {
return _bitsRequired;
}
constexpr bool isValid(const T& v) const {
return !(_max < static_cast<value_type>(v) || static_cast<value_type>(v) < _min);
}
T getValue(T v) const {
//return v - _min;
return v;
}
private:
value_type _min;
value_type _max;
size_t _bitsRequired;
};
class ObjectMemoryPosition {
public:

View File

@@ -49,6 +49,16 @@ public:
return *this;
}
/*
* range
*/
template <typename T>
Deserializer& range(T& v, RangeSpec<T> r) {
_reader.template readBits(r.valueProxy(v), r.bitsRequired());
return *this;
}
/*
* text overloads
*/

View File

@@ -47,6 +47,17 @@ public:
return *this;
}
/*
* range
*/
template <typename T>
Serializer& range(const T& v, RangeSpec<T> r) {
assert(r.isValid(v));
_writter.template writeBits(r.value(v), r.bitsRequired());
return *this;
}
/*
* text overloads
*/

View File

@@ -0,0 +1,32 @@
//
// Created by fraillt on 17.2.15.
//
#include <gmock/gmock.h>
#include "SerializationTestUtils.h"
using namespace testing;
TEST(Ranges, IntegralRanges) {
constexpr RangeSpec<int> r1{0, 31};
static_assert(r1.bitsRequired() == 5);
EXPECT_TRUE(r1.isValid(0));
EXPECT_TRUE(r1.isValid(15));
EXPECT_TRUE(r1.isValid(31));
EXPECT_FALSE(r1.isValid(-1));
EXPECT_FALSE(r1.isValid(32));
constexpr RangeSpec<MyEnumClass> r2{MyEnumClass::E1, MyEnumClass::E4};
EXPECT_TRUE(r2.isValid(MyEnumClass::E2));
EXPECT_FALSE(r2.isValid(MyEnumClass::E5));
int x= 0;
RangeSpec<int> r3{x,3};
EXPECT_THAT(r3.bitsRequired(), Eq(2));
SerializationContext ctx;
// ctx.createSerializer().range(486, {0,900});
// ctx.createSerializer().range(MyEnumClass::E4, {MyEnumClass::E1,MyEnumClass::E6});
// ctx.createSerializer().range(4.5f, {0.0f,10.0f, 10});
// ctx.createSerializer().range(4.5f, {0.0f,10.0f, 0.001f});
}

View File

@@ -28,9 +28,13 @@ SERIALIZE(MyStruct1) {
value(o.i2);
}
enum class MyEnumClass {
E1, E2, E3, E4, E5, E6
};
struct MyStruct2 {
enum MyEnum {
V1, V2, V3
V1, V2, V3, V4, V5, V6
};
MyStruct2(MyEnum e, MyStruct1 s):e1{e}, s1{s} {}