integer casts part3

This commit is contained in:
Mindaugas Vinkelis
2020-04-21 10:03:27 +03:00
committed by Mindaugas Vinkelis
parent 9cade41dbb
commit 16f637da0d
5 changed files with 62 additions and 12 deletions

View File

@@ -130,7 +130,8 @@ namespace bitsery {
template<typename T>
void readBitsInternal(T &v, size_t size) {
auto bitsLeft = size;
T res{};
using TFast = typename FastType<T>::type;
TFast res{};
while (bitsLeft > 0) {
auto bits = (std::min)(bitsLeft, details::BitsSize<UnsignedValue>::value);
if (m_scratchBits < bits) {
@@ -141,12 +142,12 @@ namespace bitsery {
}
auto shiftedRes =
static_cast<T>(m_scratch & ((static_cast<ScratchType>(1) << bits) - 1)) << (size - bitsLeft);
res = static_cast<T>(res | shiftedRes);
res = static_cast<TFast>(res | shiftedRes);
m_scratch >>= bits;
m_scratchBits -= bits;
bitsLeft -= bits;
}
v = res;
v = static_cast<T>(res);
}
void handleAlignErrors(ScratchType value, std::true_type) {
@@ -445,7 +446,6 @@ namespace bitsery {
using TIntegral = typename details::IntegralFromFundamental<TValue>::TValue;
if (first != last){
const auto distance = std::distance(first, last);
assert(distance>=0);
this->_adapter.template readBuffer<VSIZE>(reinterpret_cast<TIntegral*>(&(*first)), static_cast<size_t>(distance));
}
}

View File

@@ -182,6 +182,52 @@ namespace bitsery {
using type = uint_fast16_t;
};
template<typename T>
struct FastType {
using type = T;
};
template<>
struct FastType<uint8_t> {
using type = uint_fast8_t;
};
template<>
struct FastType<uint16_t> {
using type = uint_fast16_t;
};
template<>
struct FastType<uint32_t> {
using type = uint_fast32_t;
};
template<>
struct FastType<uint64_t> {
using type = uint_fast64_t;
};
template<>
struct FastType<int8_t> {
using type = int_fast8_t;
};
template<>
struct FastType<int16_t> {
using type = int_fast16_t;
};
template<>
struct FastType<int32_t> {
using type = int_fast32_t;
};
template<>
struct FastType<int64_t> {
using type = int_fast64_t;
};
/**
* output/input adapter base that handles endianness
*/

View File

@@ -91,18 +91,19 @@ namespace bitsery {
template<typename T>
SameSizeUnsigned<T> zigZagEncode(const T &v, std::true_type) const {
return (v << 1) ^ (v >> (BitsSize<T>::value - 1));
return static_cast<SameSizeUnsigned<T>>((v << 1) ^ (v >> (BitsSize<T>::value - 1)));
}
template<typename TResult, typename TUnsigned>
TResult zigZagDecode(TUnsigned v, std::true_type) const {
return (v >> 1) ^ (~(v & 1) + 1); // same as -(v & 1), but no warning on VisualStudio
return static_cast<TResult>((v >> 1) ^ (~(v & 1) + 1)); // same as -(v & 1), but no warning on VisualStudio
}
// write/read bytes one by one
template<typename Writer, typename T>
void writeBytes(Writer &w, const T &v) const {
auto val = v;
using TFast = typename FastType<T>::type;
auto val= static_cast<TFast>(v);
while(val > 0x7Fu) {
w.template writeBytes<1>(static_cast<uint8_t>(val | 0x80u));
val >>=7u;
@@ -112,13 +113,16 @@ namespace bitsery {
template<bool CheckErrors, typename Reader, typename T>
void readBytes(Reader &r, T &v) const {
using TFast = typename FastType<T>::type;
constexpr auto TBITS = sizeof(T)*8;
uint8_t b1{0x80u};
auto i = 0u;
TFast tmp={};
for (;i < TBITS && b1 > 0x7Fu; i +=7u) {
r.template readBytes<1>(b1);
v += static_cast<T>(b1 & 0x7Fu) << i;
tmp += static_cast<TFast>(b1 & 0x7Fu) << i;
}
v = static_cast<T>(tmp);
handleReadOverflow<Reader, T>(r, i, b1,
std::integral_constant<bool, CheckOverflow && CheckErrors>{});
}

View File

@@ -75,7 +75,7 @@ namespace bitsery {
if (_alignBeforeData)
d.adapter().align();
if (index)
obj = *std::next(std::begin(_values), index-1);
obj = static_cast<T>(*std::next(std::begin(_values), index-1));
else
fnc(d, obj);
}

View File

@@ -43,11 +43,11 @@ TValue getValue(bool isPositive, size_t significantBits) {
using TUnsigned = typename std::make_unsigned<TValue>::type;
TUnsigned mask = {};
mask = ~mask; // invert shiftByBits
mask = static_cast<TUnsigned>(~mask); // invert shiftByBits
auto shiftBy = bitsery::details::BitsSize<TValue>::value - significantBits;
mask >>= shiftBy;
mask = static_cast<TUnsigned>(mask >> shiftBy);
//cast to unsigned when applying mask
return (TUnsigned)v ^ mask;
return static_cast<TValue>(v ^ mask);
}
// helper function, that serialize and return deserialized value