mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 00:03:54 +00:00
integer casts part3
This commit is contained in:
committed by
Mindaugas Vinkelis
parent
9cade41dbb
commit
16f637da0d
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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>{});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user