blob: 8d54a906da2e797d907dfd0febb600e002f9ce90 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#pragma once
#include <util/generic/typetraits.h>
#include <limits.h>
//! Convert signed values to unsigned. Convenient for further varint encoding.
//! See https://developers.google.com/protocol-buffers/docs/encoding#types for details.
template <typename TSignedInt>
inline auto ZigZagEncode(TSignedInt n) -> std::make_unsigned_t<TSignedInt> {
static_assert(std::is_signed<TSignedInt>::value && std::is_integral<TSignedInt>::value, "Expected signed integral type.");
auto un = static_cast<std::make_unsigned_t<TSignedInt>>(n);
return (un << 1) ^ (n >> (CHAR_BIT * sizeof(TSignedInt) - 1));
}
template <typename TUnsignedInt>
inline auto ZigZagDecode(TUnsignedInt n) -> std::make_signed_t<TUnsignedInt> {
static_assert(std::is_unsigned<TUnsignedInt>::value, "Expected unsigned integral type.");
return (n >> 1) ^ -static_cast<std::make_signed_t<TUnsignedInt>>(n & 1);
}
|